web-dev-qa-db-ja.com

python-使用するpandas大きなcsv(iterateおよびchunksize)を持つ構造体

私は1100万行の約600mbの大きなcsvファイルを持っており、ピボット、ヒストグラム、グラフなどの統計データを作成したいのです。

_df = pd.read_csv('Check400_900.csv', sep='\t')
_

動作しないので、同様の投稿で繰り返しとチャンクサイズを見つけたので、

_df = pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000)
_

すべての良い、私は例えばprint df.get_chunk(5)とちょうどでファイル全体を検索することができます

_for chunk in df:
    print chunk
_

私の問題は、1つのチャンクではなく、df全体に対して以下のようなものを使用する方法がわからないことです

_plt.plot()
print df.head()
print df.describe()
print df.dtypes
customer_group3 = df.groupby('UserID')
y3 = customer_group.size()
_

私の質問がそれほど混乱しないことを願っています

22
Thodoris P

解決策、1つの大きなDataFrameを作成する必要がある場合、必要な場合はすべてのデータを一度に処理します(可能ですが、 推奨 ではありません):

次に、dfのすべてのチャンクに concat を使用します。これは、関数の出力のタイプが次のようになるためです。

df = pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000)

はデータフレームではありませんが、pandas.io.parsers.TextFileReader- ソース

tp = pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000)
print tp
#<pandas.io.parsers.TextFileReader object at 0x00000000150E0048>
df = pd.concat(tp, ignore_index=True)

インデックスの重複を避けるため、関数concatにパラメータ インデックスを無視 を追加する必要があると思います。

編集:

しかし、集約のような大きなデータを処理したい場合、高度な並列処理を提供するため、 dask を使用することをお勧めします。

22
jezrael

ここでnot need concatが必要です。 sum(map(list, grouper(tup, 1000)))の代わりにlist(tup)と書くのとまったく同じです。唯一のiteratorchunksize=1000は、全体を読み取るのではなく、1000行のDataFrameを反復処理するリーダーオブジェクトを提供します。一度に全部を知りたい場合は、これらのパラメーターを使用しないでください。

ただし、ファイル全体を一度にメモリに読み込むのが高すぎる場合(たとえば、MemoryErrorを取得するために大量のメモリを使用したり、スワップヘルドにシステムをスローしてシステムのクロールを遅くしたりする)場合は、chunksizeは.

問題は、結果のイテレータにdfという名前を付け、それをDataFrameとして使用しようとしたことです。 DataFrameではありません。 1000行のDataFrameを1つずつ提供するイテレーターです。

あなたがこれを言うとき:

私の問題は、1つのチャンクではなく、df全体に対して以下のようなものを使用する方法がわからないことです

答えは、あなたはできないです。 1つの巨大なDataFrameにすべてをロードできない場合、1つの巨大なDataFrameを使用できません。チャンクを中心にコードを書き直す必要があります。

これの代わりに:

df = pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000)
print df.dtypes
customer_group3 = df.groupby('UserID')

…このようなことをしなければなりません:

for df in pd.read_csv('Check1_900.csv', sep='\t', iterator=True, chunksize=1000):
    print df.dtypes
    customer_group3 = df.groupby('UserID')

多くの場合、行う必要があるのは、いくつかのデータを集約することです。必要な部分だけを使用して、各チャンクをはるかに小さいものに減らします。たとえば、ファイル全体をグループごとに合計する場合、各チャンクをgroupbyし、グループごとにチャンクを合計し、各グループの実行合計のシリーズ/配列/リスト/ dictを保存できます。

もちろん、巨大なシリーズを一度に合計するよりも少し複雑ですしかし、それを回避する方法はありません。 (RAMおよび/または64ビットに切り替える)を追加購入する場合を除きます。)これがiteratorchunksizeが問題を解決する方法です。このトレードオフを可能にすることで必要なときに。

8
abarnert

チャックを連結する必要があります。例えば:

df2 = pd.concat([chunk for chunk in df])

そして、df2でコマンドを実行します

4
user29791