2017-11-01 9 views
-1

パンダread_csvをチャンクサイズ500000で使用し、別のcsvファイルに書き出すことで、7億5000万行のCSVを豊かにしています。これを実行すると、約1億〜1億5千万の行を処理した後に「セグメント化エラー」が発生します。チャンクサイズのメモリリークのパンダread_csv

処理されたチャンクの数を追跡し、コードを変更して、読み取ったチャンクをスキップします。プロセスのメモリ消費量を監視する私は、チャンクをスキップしていても、それが大きく増加することがわかります。それは私が得ない部分です。そこを尋ねると、パンダのガベージコレクションに問題があるようですが、これは以前のバージョンに関連しているようです。私もメモリを6倍までのアカウントのパンダを考慮して、Pythonの2.7とパンダ0.21.0

私は十分なはず30ギガバイトのRAMを搭載したr3.xlargeのEC2インスタンス上でこれをやっているを使用していますオーバーヘッド。

コードの要約:

i = 0 
for chunk in pd.read_csv(filename,chunksize=500000,names=colnames): 
    if i <= 349500000: # Previously processed chunks 
     i = i+chunksize 
     print 'Skipping chunk ', i 
     continue 
    enriched_chunk = enrich_df(chunk, users_df) 
    enriched_chunk.to_csv('enriched.csv', mode='a', header=False, index=False) 


def enrich_df(c, users_df): 
    d = pd.merge(c, users_df, how='left', left_on='user_id', right_on='userId') 
    return d 

テーブルusers_dfはメモリに保持され、比較的小さなテーブルです。

答えて

0

私は単純なテストスクリプトを書いており、エラーを再現することはできません。私はPython 3.6.1とPandas 0.20.3を使用しています。

このテストスクリプトでは、一定の306 MBのRAMを使用しています(少なくとも最初の1億行ではまだ実行中です)。

RAM usage of test script

このスクリプトを試してみて、それはまだあなたとメモリリークを生成する場合見ることができましたか?これは、デバッグの出発点として役立ちます。

import os 
import time 

import numpy as np 
import pandas as pd 
import matplotlib.pylab as plt 

SOURCE = 'test.csv' 
CHUNCKSIZE = int(5e5) 

def main(): 

    if not os.path.exists(SOURCE): 
     df = pd.DataFrame(np.random.rand(1000000, 4), columns=list('ABCD')) 
     df.to_csv(SOURCE) 
     del df 
    print("df %s ready" %(SOURCE)) 

    i=0; lines=[]; timings = [] 
    while(i < int(7e8)): 
     t = time.time() 
     print(i, end = ' ') 
     i += CHUNCKSIZE 
     chunk = pd.read_csv(SOURCE, chunksize=CHUNCKSIZE) 
     chunk = pd.concat(chunk, ignore_index=True) 
     chunk.to_csv('enriched.csv', mode='a', header=False, index=False) 
     print(" in %.3f seconds" %(time.time() -t)) 
     lines.append(i) 
     timings.append(time.time()-t) 


    plt.figure(figsize=(10,5)) 
    plt.plot(lines, timings, 'o-') 
    plt.xlabel("Nr of lines"); plt.ylabel("Time for last chunck") 
    plt.show() 




if __name__ == "__main__": 
    st = time.time() 
    main() 
    print("--- total runtime %.3f seconds ---" %(time.time() - st)) 
関連する問題