web-dev-qa-db-ja.com

DataFrameの連結が指数関数的に遅くなるのはなぜですか?

主にデータをバケットに処理して、pd.get_dummies(df[col])を使用して特定の列に機能のバイナリマトリックスを作成するために、DataFrameを処理する関数があります。

この関数を使用してすべてのデータを一度に処理する(メモリ不足になり、iPythonがクラッシュする)のを避けるために、次を使用して大きなDataFrameをチャンクに分割しました。

_chunks = (len(df) / 10000) + 1
df_list = np.array_split(df, chunks)
_

pd.get_dummies(df)は_df[col]_の内容に基づいて新しい列を自動的に作成し、これらは_df_list_のdfごとに異なる可能性があります。

処理後、次を使用してDataFrameを連結します。

_for i, df_chunk in enumerate(df_list):
    print "chunk", i
    [x, y] = preprocess_data(df_chunk)
    super_x = pd.concat([super_x, x], axis=0)
    super_y = pd.concat([super_y, y], axis=0)
    print datetime.datetime.utcnow()
_

最初のチャンクの処理時間は完全に許容できますが、チャンクごとに増加します!これは、preprocess_data(df_chunk)とは関係ありません。理由はありません。この時間の増加は、pd.concat()の呼び出しの結果として発生していますか?

以下のログをご覧ください:

_chunks 6
chunk 0
2016-04-08 00:22:17.728849
chunk 1
2016-04-08 00:22:42.387693 
chunk 2
2016-04-08 00:23:43.124381
chunk 3
2016-04-08 00:25:30.249369
chunk 4
2016-04-08 00:28:11.922305
chunk 5
2016-04-08 00:32:00.357365
_

これを高速化する回避策はありますか?処理する2900のチャンクがあるので、助けてください!

Pythonで他の提案を開いてください!

23
jfive

連結するたびに、データのコピーを返します。

チャンクのリストを保持し、最後のステップとしてすべてを連結します。

df_x = []
df_y = []
for i, df_chunk in enumerate(df_list):
    print "chunk", i
    [x, y] = preprocess_data(df_chunk)
    df_x.append(x)
    df_y.append(y)

super_x = pd.concat(df_x, axis=0)
del df_x  # Free-up memory.
super_y = pd.concat(df_y, axis=0)
del df_y  # Free-up memory.
7
Alexander