[英]How to efficiently output dictionary as csv file using Python's csv module? Out of memory error
我正在嘗試使用Python的CSV模塊將字典列表序列化為csv文本文件。 我的列表有大約13,000個元素,每個元素都是一個包含〜100個鍵的字典,由簡單的文本和數字組成。 我的函數“dictlist2file”只是調用DictWriter來序列化它,但是我的內存錯誤。
我的功能是:
def dictlist2file(dictrows, filename, fieldnames, delimiter='\t',
lineterminator='\n', extrasaction='ignore'):
out_f = open(filename, 'w')
# Write out header
if fieldnames != None:
header = delimiter.join(fieldnames) + lineterminator
else:
header = dictrows[0].keys()
header.sort()
out_f.write(header)
print "dictlist2file: serializing %d entries to %s" \
%(len(dictrows), filename)
t1 = time.time()
# Write out dictionary
data = csv.DictWriter(out_f, fieldnames,
delimiter=delimiter,
lineterminator=lineterminator,
extrasaction=extrasaction)
data.writerows(dictrows)
out_f.close()
t2 = time.time()
print "dictlist2file: took %.2f seconds" %(t2 - t1)
當我在我的字典上嘗試這個時,我得到以下輸出:
dictlist2file: serializing 13537 entries to myoutput_file.txt
Python(6310) malloc: *** mmap(size=45862912) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Traceback (most recent call last):
...
File "/Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/csv.py", line 149, in writerows
rows.append(self._dict_to_list(rowdict))
File "/Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/csv.py", line 141, in _dict_to_list
return [rowdict.get(key, self.restval) for key in self.fieldnames]
MemoryError
知道是什么原因引起的嗎? 該列表只有13,000個元素,字典本身非常簡單和小(100個鍵),所以我不明白為什么這會導致內存錯誤或效率低下。 它需要幾分鍾才能得到內存錯誤。
謝謝你的幫助。
DictWriter.writerows(...)
獲取您傳遞給它的所有DictWriter.writerows(...)
並創建(在內存中)一個新的列表列表,每行一個。 因此,如果您有大量數據,我可以看到如何彈出MemoryError
。 您可以采取兩種方式:
DictWriter.writerow
一次。 雖然這意味着很多寫作。 DictWriter.writerows
。 減少IO,但是你可以避免分配大量的內存。 您可能會絆倒內部Python問題。 我會在bugs.python.org上報告。
我沒有回答csv發生的事情,但我發現以下替代品在不到幾秒的時間內將字典序列化為一個文件:
for row in dictrows:
out_f.write("%s%s" %(delimiter.join([row[name] for name in fieldnames]),
lineterminator))
其中dictrows是由dictReader從csv生成的字典的生成器,fieldnames是一個字段列表。
任何關於為什么csv表現不同的想法都將非常感激。 謝謝。
你說如果你循環使用data.writerow(single_dict)它仍然會遇到問題。 輸入代碼以顯示每100行的行數。 在獲得內存錯誤之前處理了多少個dicts? 運行更多或更少的進程來吸收更多或更少的內存...它失敗的地方會有所不同嗎?
什么是max(len(d) for d in dictrows)
?) 這些字符串中的字符串有多長?
你有多少免費記憶?
更新:看看Dictwriter是否是問題; 消除它並使用基本的csv功能:
writer = csv.writer(.....)
for d in dictrows:
row = [d[fieldname] for fieldname in fieldnames]
writer.writerow(row)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.