我有一个代码可以完美地工作,但是它占用了太多内存。在
本质上,这段代码需要一个输入文件(我们称之为索引,即用两列制表符分隔)在第二个输入文件中搜索第1列中的对应项(将其称为数据,即4列制表符分隔),然后将其替换为索引文件中的信息。在
索引的一个例子是:
amphibian anm|art|art|art|art
anaconda anm
aardvark anm
数据示例如下:
^{2}$因此,当用索引中的相应信息替换数据列1中的值时,结果如下:
anm-n is green
art-n is green
anm-n eats mice
anm-n eats plants
我将代码分成步骤,因为这样做的目的是计算数据文件中列2和列3的替换项(数据中的列4)的值的平均值。此代码获取数据文件中插槽填充器的总数,并将步骤3中使用的值求和。在
预期结果如下:
anm second hello 1.0
anm eats plants 1.0
anm first heador 0.333333333333
art first heador 0.666666666667
在步骤1、2和3中,我多次打开同一个输入文件(即3次),因为我需要创建几个需要按一定顺序创建的字典。 有没有方法可以优化我打开同一个输入文件的次数?
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
from collections import defaultdict
import datetime
print "starting:",
print datetime.datetime.now()
mapping = dict()
with open('input-map', "rb") as oSenseFile:
for line in oSenseFile:
uLine = unicode(line, "utf8")
concept, conceptClass = uLine.split()
if len(concept) > 2:
mapping[concept + '-n'] = conceptClass
print "- step 1:",
print datetime.datetime.now()
lemmas = set()
with open('input-data', "rb") as oIndexFile:
for line in oIndexFile:
uLine = unicode(line, "latin1")
lemma = uLine.split()[0]
if mapping.has_key(lemma):
lemmas.add(lemma)
print "- step 2:",
print datetime.datetime.now()
featFreqs = defaultdict(lambda: defaultdict(float))
with open('input-data', "rb") as oIndexFile:
for line in oIndexFile:
uLine = unicode(line, "latin1")
lemmaTAR, slot, filler, freq = uLine.split()
featFreqs[slot][filler] += int(freq)
print "- step 3:",
print datetime.datetime.now()
classFreqs = defaultdict(lambda: defaultdict(lambda: defaultdict(float)))
with open('input-data', "rb") as oIndexFile:
for line in oIndexFile:
uLine = unicode(line, "latin1")
lemmaTAR, slot, filler, freq = uLine.split()
if lemmaTAR in lemmas:
senses = mapping[lemmaTAR].split(u'|')
for sense in senses:
classFreqs[sense][slot][filler] += (int(freq) / len(senses)) / featFreqs[slot][filler]
else:
pass
print "- step 4:",
print datetime.datetime.now()
with open('output', 'wb') as oOutFile:
for sense in sorted(classFreqs):
for slot in classFreqs[sense]:
for fill in classFreqs[sense][slot]:
outstring = '\t'.join([sense, slot, fill,\
str(classFreqs[sense][slot][fill])])
oOutFile.write(outstring.encode("utf8") + '\n')
对于如何优化此代码以处理大型文本文件(例如,>;4GB)有何建议?在
如果我能正确理解代码,就不需要引理集了。您可以删除步骤1并替换步骤3中的签入
直接与
^{pr2}$关于内存问题-你有没有试着减少你保存在内存中的数据的开销?当前您正在使用嵌套词典。也许一个扁平的数据结构会占用更少的内存,例如一维featfreq需要一个由“%slot-%filler”构造的键。在
相关问题 更多 >
编程相关推荐