データセットが大きすぎてメモリに収まらない場合に、Python でグループ化操作を行う簡単な方法/モジュールはありますか?
通常はパンダを使用しますが、大規模なデータセットでは機能しません。
データセットが大きすぎてメモリに収まらない場合に、Python でグループ化操作を行う簡単な方法/モジュールはありますか?
通常はパンダを使用しますが、大規模なデータセットでは機能しません。
コメントで、@steboc は可能な解決策として sqlite を使用することに言及しました。このためのバックエンドとして任意のデータベースを使用できますが、sqlite はかなり高速であり、セットアップはほとんど必要ありません。大量のジャンクを sqlite に書き込み、それをグループで読み戻す例を次に示します。
いくつかのパッケージをロードして環境をセットアップすることから始めます。
import pandas as pd
import sqlite3
import string
## connect to a db. This db will be created if it does not exist
conn = sqlite3.connect('example.db')
c = conn.cursor()
np.random.seed(123)
## create some random data in a pandas dataframe
n = 1000000
c = 10
30 回ループしてみましょう。そのたびに、1mm レコード、10 個の数値フィールド、および単純な文字のキーを持つデータフレームを作成します。そのデータフレームを sqlite データベースに挿入します。ループの最後で、データベースに 30mm 行が作成されます。私の MBP では、これに約 15 分かかります。
%%time
for i in arange(30):
df = pd.DataFrame(np.random.randn(n, c), columns=list(map(chr, range(65, 65+c))))
df['key'] = string.ascii_letters[i]
df.to_sql(name='test_table', if_exists='append', con=conn)
ここで、フィールドの値によってグループ化されたこのすべてのデータに対して操作を行う場合、key
最初にキーのすべての一意の値を取得する必要があります。1 つの方法は、これを行うことです。
%%time
keys_df = pd.read_sql(sql='SELECT DISTINCT key FROM test_table', con=conn)
keys_df
これでkeys_df
、「キー」のすべての一意の値を含む 1 つの列を持つデータフレームが得られました。これで、各グループを繰り返し処理し、データベースからそのグループのみを抽出して、グループ化された操作を実行できます。次の例は、簡単な describe() を実行します。
%%time
for row in keys_df.iterrows():
tempdf = pd.read_sql(sql='SELECT * FROM test_table WHERE key=\'' + row[1][0] + '\';', con=conn)
## do anything you want with your group here.
## we'll print describe just for fun
print tempdf.describe()
print ""
明らかに実際には、値をデータ構造に入れます。
これが、sqlite と pandas を使用してデータのグループを反復処理する方法を説明するのに役立つことを願っています。
Blaze プロジェクトは、データセットをチャンク化し、各チャンクで Pandas を使用することで、大規模なデータセットを喜んで管理します。Blazeのアウト オブ コア ドキュメントに興味があるかもしれません。NYC Taxi データセットの明示的な例を次に示します。
より遅い純粋な Python ソリューションを好む場合は、toolz
プロジェクトに興味があるかもしれません。ストリーミング分析に関するドキュメントは次のとおりです