使用pickle将庞大的二元组字典保存到文件
我有个朋友写了一个小程序。这个textFile
文件有1.2GB大(相当于7年的报纸内容)。他成功地创建了一个字典,但在用pickle把它写入文件时,程序就卡住了。
import sys
import string
import cPickle as pickle
biGramDict = {}
textFile = open(str(sys.argv[1]), 'r')
biGramDictFile = open(str(sys.argv[2]), 'w')
for line in textFile:
if (line.find('<s>')!=-1):
old = None
for line2 in textFile:
if (line2.find('</s>')!=-1):
break
else:
line2=line2.strip()
if line2 not in string.punctuation:
if old != None:
if old not in biGramDict:
biGramDict[old] = {}
if line2 not in biGramDict[old]:
biGramDict[old][line2] = 0
biGramDict[old][line2]+=1
old=line2
textFile.close()
print "going to pickle..."
pickle.dump(biGramDict, biGramDictFile,2)
print "pickle done. now load it..."
biGramDictFile.close()
biGramDictFile = open(str(sys.argv[2]), 'r')
newBiGramDict = pickle.load(biGramDictFile)
提前谢谢大家。
补充说明
对于感兴趣的人,我简单解释一下这个程序的功能。假设你有一个大致格式如下的文件:
<s>
Hello
,
World
!
</s>
<s>
Hello
,
munde
!
</s>
<s>
World
domination
.
</s>
<s>
Total
World
domination
!
</s>
<s>
是句子的分隔符。- 每行一个单词。
这个程序会生成一个二元组字典,供以后使用。
大概是这样的:
{
"Hello": {"World": 1, "munde": 1},
"World": {"domination": 2},
"Total": {"World": 1},
}
希望这能帮到你。目前的策略改成使用mysql,因为sqlite实在不行(可能是因为文件太大了)
5 个回答
1
你真的需要把所有数据都放在内存里吗?如果你想用字典或pickle的方法,可以简单地把数据分成每年一个文件或者每月一个文件。
另外,要记住字典里的数据是没有顺序的,这样一来,如果你需要对这么多数据进行排序,可能会遇到麻烦。如果你想搜索或者排序数据的话,当然...
总之,我觉得之前提到的数据库方法是最灵活的,特别是从长远来看...
1
一种解决办法是使用 buzhug,而不是使用pickle。buzhug是一个纯Python的解决方案,语法也很符合Python的风格。我把它看作是比shelve等工具更进一步的选择。它可以处理你提到的数据大小。每个字段的大小限制是2GB(每个字段会存储在一个单独的文件中)。