web-dev-qa-db-ja.com

メモリを使い果たすことなく、SQLクエリから大きなpandasデータフレームを作成するには?

MS SQL Serverデータベースから500万件を超えるレコードのテーブルを照会するのに問題があります。すべてのレコードを選択したいのですが、多くのデータをメモリに選択するとコードが失敗するようです。

これは動作します:

import pandas.io.sql as psql
sql = "SELECT TOP 1000000 * FROM MyTable" 
data = psql.read_frame(sql, cnxn)

...しかし、これは機能しません:

sql = "SELECT TOP 2000000 * FROM MyTable" 
data = psql.read_frame(sql, cnxn)

このエラーを返します:

File "inference.pyx", line 931, in pandas.lib.to_object_array_tuples
(pandas\lib.c:42733) Memory Error

私は here を読みました。csvファイルからdataframeを作成するときに同様の問題があり、回避策はこのような 'iterator'および 'chunksize'パラメーターを使用することです:

read_csv('exp4326.csv', iterator=True, chunksize=1000)

SQLデータベースからクエリするための同様のソリューションはありますか?そうでない場合、推奨される回避策は何ですか?他の方法を使用して、レコードをチャンクで読み取る必要がありますか?パンダで大きなデータセットを操作することについて、少し議論します こちら ですが、SELECT *クエリを実行するのは大変な作業のようです。確かにもっと簡単なアプローチがあります。

33
slizb

更新:Pandasにチャンクロードの組み込みサポートが追加されました。

次のように、入力テーブルをチャンク単位で読み取り、個々の断片から完全なデータフレームを組み立てるだけで済みます。

import pandas as pd
import pandas.io.sql as psql
chunk_size = 10000
offset = 0
dfs = []
while True:
  sql = "SELECT * FROM MyTable limit %d offset %d order by ID" % (chunk_size,offset) 
  dfs.append(psql.read_frame(sql, cnxn))
  offset += chunk_size
  if len(dfs[-1]) < chunk_size:
    break
full_df = pd.concat(dfs)

データフレーム全体が大きすぎてメモリに収まらない可能性もあります。その場合、選択する行または列の数を制限する以外のオプションはありません。

32
ThePhysicist

コメントで述べたように、pandas 0.15から始まり、read_sqlチャンク単位でクエリを読み取り、処理します。

sql = "SELECT * FROM My_Table"
for chunk in pd.read_sql_query(sql , engine, chunksize=5):
    print(chunk)

リファレンス: http://pandas.pydata.org/pandas-docs/version/0.15.2/io.html#querying

40
ksindi

コードソリューションと備考。

# Create empty list
dfl = []  

# Create empty dataframe
dfs = pd.DataFrame()  

# Start Chunking
for chunk in pd.read_sql(query, con=conct, ,chunksize=10000000):

    # Start Appending Data Chunks from SQL Result set into List
    dfl.append(chunk)

# Start appending data from list to dataframe
dfs = pd.concat(dfl, ignore_index=True)

しかし、私のメモリ分析では、各チャンクが抽出された後にメモリが解放されても、リストはどんどん大きくなり、そのメモリを占有しているため、ネットの空きRAMが増加しないことがわかりました。

著者/他の人が言っていることを聞きたいです。

1