私はこれにsimilar questionを見ましたが、私の苦境は新しい質問を保証するのに十分な方法で違うと思います。なぜPython辞書はあまりにも多くのメモリを使用していますか?
私はcsvファイルを開き、ディメンションとメトリックのリストに基づいてjsonのような辞書構造にデータを集約する関数を作成しました。
問題は、0.97GBのファイルを開くときに問題が発生します。私のプロセスを見ると、pythonプロセスは約1.02GBのメモリを使用しています。私はファイルのフィールドのほんの一部を選択していることを念頭に置いて、データはと集計されています。また、辞書変数は関数から返される唯一のものなので、関数が実行された後にメモリに残っている唯一のものではないでしょうか?誰かが私の辞書オブジェクトがそんなに多くのメモリを使用している理由を知っていますか?
** EDIT - csv.reader()がジェネレータであるため、一度にファイル全体を読み込むこともないので、すべてのメモリを使用する辞書オブジェクトでなければなりません。
私はWindowsでPython 2.7を使用しています。
import json
import inspect
from pprint import pprint
import csv
from datetime import datetime
import sys
def jsonify_csv(fileString, dimensions, metrics, struc = {}):
with open(fileString, 'rb') as f:
reader=csv.reader(f)
headings = reader.next()
i = 0
for line in reader:
i+=1
row = {headings[i]:v for i, v in enumerate(line)}
pointer = struc
for dimension in dimensions:
if dimension == 'date':
val = str(datetime.strptime(row[dimension], "%d/%m/%Y").date().month)
else:
val = str(row[dimension])
pointer.setdefault(val, {})
pointer = pointer[val]
for metric in metrics:
pointer.setdefault(metric, 0.0)
try:
pointer[metric] += float(row[metric])
except ValueError:
pass
return struc
start = datetime.today()
dims = ['brand', 'source', 'affiliate', 'country', 'store', 'salesbundle', 'product', 'ordertype', 'returncode', 'supplier', 'category']
metrics = ['sales', 'qty', 'cogs', 'carriagereclaim', 'Carriage Charged Carrier', 'carriage_est', 'mktg_est', 'mktg_cost', 'royalty', 'finance', 'scrap_cost', 'mp_cost', 'budgetsales', 'budgetcosts', 'BSTD', 'budgetaftersales', 'budgetscrap', 'budgetcarriagerecovery', 'budgetcarriagepaid', 'budgetmetapack', 'budgetmarketing', 'budgetaffiliate', 'budgetoffline', 'budgetroyalty', 'budgetfinance', 'bundle_qty', 'misc_adjustments']
jsonified = jsonify_csv('PhocasSales_2015+.csv', dims, metrics)
print 'file opened', datetime.today()-start
stop = raw_input("waiting...")
デフォルトパラメータとして可変オブジェクトを使用しないでください:
はこれを試してみてください。 http://docs.python-guide.org/en/latest/writing/gotchas/ – cdarke
を参照してください。@cdarkeさんのお返事ありがとうございます。理由を詳しく説明してください。私がstruc = {}をインクルードした理由は、たとえば、5つの別々のファイルを開き、それらがすべて同じオブジェクトの別々のブランチの下に格納されるようにするためです。例えばx = {file1:{}、file2:{}} –
各呼び出しは同じ辞書を使用します。私が与えたリンクを読んだ?コンパイル時に空の辞書 '{}'が関数の属性として作成されます。デフォルトを使用して関数を28回呼び出した場合、28種類の辞書は取得されず、すべて同じものを共有します。デフォルト値を 'None'に設定し、関数の本体でその値をテストします。 – cdarke