2017-08-16 1 views
2

膨大なデータサイズのため、私たちはパンダを使ってデータを処理しましたが、非常に奇妙な現象が発生しました。疑似コードは次のようになります。chunkksizeオプションのpandas.read_csv関数の異常なインデックス機構

reader = pd.read_csv(IN_FILE, chunksize = 1000, engine='c') 
for chunk in reader: 
    result = [] 
    for line in chunk.tolist(): 
     temp = complicated_process(chunk) # this involves a very complicated processing, so here is just a simplified version 
     result.append(temp) 
    chunk['new_series'] = pd.series(result) 
    chunk.to_csv(OUT_TILE, index=False, mode='a') 

結果の各ループが空でないことを確認できます。しかし、初めてのループでは、chunk['new_series'] = pd.series(result)行に結果があり、残りは空です。したがって、出力の最初のチャンクだけがnew_seriesを含み、残りは空です。

ここで何か不足しましたか?前もって感謝します。

答えて

3

ループの上にresultを宣言する必要があります。そうしないと、各チャンクで再初期化されます。

result = [] 
for chunk in reader: 
    ... 

あなた以前の方法は、機能的に同等である。また、

for chunk in reader: 
    del result # because it is being re-assigned on the following line. 
    result = [] 
    result.append(something) 
print(result) # Only shows result from last chunk in reader (the last loop). 

、私が推薦する:

chunk = chunk.assign(new_series=result) # Instead of `chunk['new_series'] = pd.series(result)`. 

を私はあなたがあなたのfor loopline変数で何かをやっていると仮定しています、上記のあなたの例では使用されていません。

+1

ありがとうございます。はい、あなたは提案が働いています。しかし、私はなぜresult = []が動くのか理解できません。これは私にとって非常に厄介です。少し詳しく説明できますか?どうもありがとう! – acepor

+0

ありがとうございました。しかし、これはまさに問題を引き起こしたものではありません。各チャンクの索引付けを追跡したとき、私はそれらが個々ではないことを発見しました。各チャンクは0からインデックスを開始すると仮定しましたが、実際はそうではありません。この場合、各チャンクのインデックスはCSV全体のサブセットであるため、そのインデックスはCSVから派生しています。これが問題の原因です。上記の例では、 'pandas.to_csv'は最後のチャンクではなく、最初のチャンクの結果のみを書き込みます。しかし、私はあなたのインスピレーションに感謝します。そうでなければ、私は本当にこれを解決する方法を知らなかった。 – acepor

+0

私の 'chunk = chunk.assign(new_series = result)'勧告を使いましたか?私はあなたがこの問題を抱えているとは思わない。 – Alexander

1

より良い解決策は、これを次のようになります。

reader = pd.read_csv(IN_FILE, chunksize = 1000, engine='c') 
for chunk in reader: 
    result = [] 
    for line in chunk.tolist(): 
     temp = complicated_process(chunk) # this involves a very complicated processing, so here is just a simplified version 
     result.append(temp) 
    new_chunk = chunk.reset_index() 
    new_chunk = new_chunk.assign(new_series=result) 
    new_chunk.to_csv(OUT_TILE, index=False, mode='a') 

注意:各チャンクのインデックスは、個々のではなく、ファイル全体を得ています。各ループから新しいシリーズを追加すると、チャンクはファイル全体からインデックスを継承します。したがって、各チャンクのインデックスと新しいシリーズは一致しません。

@Alexanderのソリューションが機能しますが、resultは膨大になる可能性があります。そのため、あまりにも多くのメモリを占有します。

ここでの新しいソリューションは、new_chunk = chunk.reset_index()を実行して各チャンクのインデックスをリセットし、resultは各ループ内でリセットされます。これにより、多くのメモリが節約されます。

関連する問題