web-dev-qa-db-ja.com

Pandas SQLチャンクサイズ

これは、プログラミングよりも理解の問題です。私はPandasとSQLにかなり慣れています。特定のチャンクサイズでSQLからデータを読み取るためにpandasを使用しています。 pandas as pd

df = pd.read_sql_query('select name, birthdate from table1', chunksize = 1000)

私が理解していないのは、チャンクサイズを指定しない場合、データはメモリに保存され、メモリが増加するのを見ることができますが、チャンクサイズを指定した場合、メモリ使用量はそれほど高くありません。

私が持っているのは、このdfに現在アクセスできる配列の数が含まれていることです

for df_array in df:
    print df.head(5)

ここで理解できないのは、SQLステートメントの結果全体がメモリに保持されているかどうか、つまりdfが複数の配列を保持するオブジェクトであるか、またはこれらがSQLクエリによって作成された一時テーブルを指すポインターのようなものであるかどうかです。

このプロセスが実際にどのように機能しているかについての理解を深めることができてとても嬉しいです。

18
Nitin Kumar

2つのオプションと、両方のケースで何が起こるかを考えてみましょう。

  1. chunksizeはNone(デフォルト値):
    • パンダはデータベースにクエリを渡します
    • データベースはクエリを実行します
    • パンダは、chunksizeがNoneであることを確認します
    • パンダは、結果テーブルのすべての行を一度に受信することをデータベースに伝えます
    • データベースは結果テーブルのすべての行を返します
    • パンダは結果テーブルをメモリに保存し、データフレームにラップします
    • これで、データフレームを使用できます
  2. なしのチャンクサイズ:
    • パンダはデータベースにクエリを渡します
    • データベースはクエリを実行します
    • パンダは、チャンクサイズに何らかの値があることをチェックして確認します
    • パンダはクエリイテレータを作成し(通常の「while True」ループは、データベースにこれ以上データが残っていないと言われたときに中断します)、結果テーブルの次のチャンクが必要になるたびに繰り返します
    • パンダは、チャンクサイズの行を受信することをデータベースに伝えます
    • データベースは結果テーブルから次のチャンクサイズの行を返します
    • パンダは次のチャンクサイズの行をメモリに保存し、データフレームにラップします
    • これで、データフレームを使用できます

詳細については pandas\io\sql.py モジュールをご覧ください。

25
prusya

chunksizeを指定しない場合、クエリの完全な結果が一度にデータフレームに入れられます。

chunksizeを指定すると、_read_sql_query_の戻り値は複数のデータフレームの反復子になります。これは、次のように繰り返し処理できることを意味します。

_for df in result:
    print df
_

また、各ステップでdfはクエリの一部のデータを保持するデータフレーム(配列ではありません!)です。これに関するドキュメントを参照してください: http://pandas.pydata.org/pandas-docs/stable/io.html#querying

メモリに関する質問に答えるには、データベースからデータを取得する際にexecutefetchの2つのステップがあることを知っておく必要があります。
最初にクエリが実行され(result = con.execute())、次にこの結果セットからタプルのリストとしてデータがフェッチされます(data = result.fetch())。フェッチするときに、一度にフェッチする行数を指定できます。そして、これはchunksizeを指定したときにpandasが行うことです。
しかし、多くのデータベースドライバーは、データをフェッチするときだけでなく、実行ステップですべてのデータを既にメモリに入れています。したがって、その点で、メモリにとっては重要ではありません。事実とは別に、データをDataFrameにコピーすることは、chunksizeを使用して反復している間、異なるステップでのみ発生します。

20
joris