2016-09-19 2 views
0

선반 모듈을 사용하여 몇 가지 사전을 저장하려고하지만 크기에 문제가 있습니다. 필자는 Python 3.5.2와 최신 쉘브 모듈을 사용합니다.Python 선반 모듈의 크기 문제

나는 단어 목록을 가지고 있으며 bigrams (문자 레벨)에서 단어로 맵을 만들고 싶다. 구조는 다음과 같습니다.

'aa': 'aardvark', 'and', ... 
'ab': 'absolute', 'dab', ... 
... 

약 130 만 단어로 구성된 대용량 파일을 읽었습니다. 따라서 사전은 상당히 커집니다. 이 코드입니다 :

나는 일반 파이썬 사전을 사용하여이 코드를 실행
self.bicharacters // part of class 
def _create_bicharacters(self): 
    ''' 
    Creates a bicharacter index for calculating Jaccard coefficient. 
    ''' 
    with open('wordlist.txt', encoding='ISO-8859-1') as f: 
     for line in f: 

      word = line.split('\t')[2] 

      for i in range(len(word) - 1): 
       bicharacter = (word[i] + word[i+1]) 

       if bicharacter in self.bicharacters: 
        get = self.bicharacters[bicharacter] 
        get.append(word) 
        self.bicharacters[bicharacter] = get 
       else: 
        self.bicharacters[bicharacter] = [word] 

, 내가 문제로 실행하지 못했지만, 나는 또한 필요에 의한 프로그램의 나머지 부분에 메모리 리소스 이러한 종류의를 아끼지 수 꽤 큰 메모리 풋 프린트.

그래서 선반 모듈을 사용해 보았습니다. 그러나 shelve를 사용하여 위의 코드를 실행하면 디스크에 더 이상 메모리가 없기 때문에 잠시 후 프로그램이 중지되고 shelve db는 약 120GB이고 여전히 파일에서 1.3M 단어 목록의 절반도 읽지 못했습니다 . 여기서 내가 뭘 잘못하고 있니?

+0

왜'pip'와 함께'shelve'를 설치 했습니까? 이것은 표준 라이브러리의 일부이며, 기본적으로 ['pickle'] (https://docs.python.org/3/library/pickle.html)과 ['dbm'] (https : // docs .python.org/3/library/dbm.html). 동일한 이름으로 된 [PyPI 패키지] (https://pypi.python.org/pypi/shelve)는 완전히 다른 것입니다. –

+0

대신 데이터베이스를 사용하려면이 도구를 다시 작성해야합니다. [dbm 형식] (https://en.wikipedia.org/wiki/Dbm)은 그러한 대규모 데이터 세트에 정확히 최적화되어 있지 않습니다. –

+0

@MartijnPieters 죄송합니다. 핏을 통해 설치하지 않았고 다른 것과 혼합했습니다. –

답변

2

여기의 문제는 키의 수가 많지는 않지만 각 키는 단어 목록을 참조합니다.

하나의 (거대한) 사전으로 메모리에 있지만 단어가 단순히 목록간에 공유되기 때문에 큰 문제는 아닙니다. 각 목록은 다른 객체에 대한 참조 시퀀스 일 뿐이며이 객체의 많은 부분이 동일합니다. 단어 당 하나의 문자열 만 참조하면됩니다. shelve에서

하지만, 각 값은 산세되고리스트 내의 단어의 콘크리트 복사 각 값에 대한 저장되어야하는 것을 의미 별도로 저장된다. 설치 프로그램이 많은 단어 목록에 주어진 단어를 추가하기 때문에 데이터 요구량이 크게 증가합니다.

여기서 SQL 데이터베이스를 사용하도록 전환하고 싶습니다. Python은 sqlite3 번들과 함께 제공됩니다. 개별 단어에 대해 하나의 표를 만들고 두 번째 표를 각 가능한 bigram에 대해 만들고 두 번째 표를 두 점 사이에 단순히 연결하는 경우 (bigram 행 ID와 단어 행 ID를 연결하는 다 대다 매핑)이 작업을 매우 수월하게 수행 할 수 있습니다 효율적으로 그런 다음 SQLite는 메모리와 인덱스를 관리하는 데 매우 능숙하므로 매우 효율적인 조회를 수행 할 수 있습니다.