簡體   English   中英

如何使用Python的csv模塊有效地將字典輸出為csv文件? 內存不足錯誤

[英]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 您可以采取兩種方式:

  1. 自己迭代列表並為每個列表調用DictWriter.writerow一次。 雖然這意味着很多寫作。
  2. 將行批處理到較小的列表並為它們調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM