2016-08-16 11 views
0

用データフレームを構築し、私は次のようなテーブルがある:SQL列の個別の値を超える反復処理し、各値

|A|B|C|D| 
|---|---|---|---| 
|1|b1|c1|d1| 
|1|b2|c2|d2| 
|2|b3|c3|d3| 
|2|b4|c4|d4| 

私はAの異なる値を反復してパンダを構築したいと思いますデータフレームを残りの列から除外し、そのテーブルを使用して計算を行います。私は、次のことを試してみました:

import sqlite3 
import pandas as pd 
conn = sqlite3.connection('my_db.db') 
c = conn.cursor() 
for entry in c.execute("SELECT DISTINCT A in table): 
    df = pd.DataFrame(c.execute("SELECT * FROM table WHERE A = ?", (entry[0],)).fetchall()) 

データフレームを構築する2番目のカーソルオブジェクトiが反復処理されたカーソルオブジェクトを上書きするので、これは動作しません。また、2つのカーソルオブジェクトを持つことができないことも発見しました。これを回避するにはどうすればよいですか?

答えて

0

エンド・ソリューションは、私は同様にthis postが有用であることが判明chunksize

pandas.read_sqlを使用することでした。

import sqlite3 
import pandas as pd 
conn = sqlite3.connection('my_db.db') 
for df in pd.read_sql("SELECT * from table ORDER BY A ASC", conn, chunksize = 100000): 
    group = df.groupby('A') 
    last = group.first().tail(1).index.values[0] 
    last_a = 0 
    for a, g_df in group: 
     if (a == last_a): 
      g_df = l_df.append(g_df) 

     ....calculations.... 

     if (a == last): 
      l_df = g_df 
      l_a = a 

2つの異なるチャンクに分割されたgroupbyデータフレームを結びつけるロジックを持つことが本当に重要です。

1

あなたはこの操作をパンダ自体でやりたくない特別な理由はありますか?あなたは、単にそのようにそれを行うことができます:(それは巨大なデータセットでなければ)

parent_df = pd.read_sql(c, "SELECT * from table") 
for name, group in parent_df.groupby('A'): 
    print(name, group.head()) 

それとも

parent_df.set_index('A', inplace=True) 
parent_df.head(20) 
+0

残念ながら、テーブル全体を一度にメモリに読み込むことができないので、私はそのような方法でパンダを使用することはできません。しかし、それはオプションです知って良い! – deltap

+0

'pandas.read_sql'には' chunksize' kwagがあります。 SQLクエリを使ってテーブルをソートし、 'chunksize'オプションを使います。 – Kartik

1

は、あなたがデータフレームに興味を持っているすべてのデータを入れて、その後のデータセットをフィルタリングします。

df = pd.DataFrame(c.execute("SELECT * FROM table").fetchall()) 
distict_a = df['A'].unique() 
for a in distinct_a: 
    df_for_this_a = df.query[df.A == a] 
+0

これはうまくいくのですが、テーブル全体をメモリに読み込むことができないという難点があります。 – deltap

1

(dictのルートがグローバル環境で複数のDFSを回避)パンダのread_sql(カーソル値を渡すことでパラメータを持つ)と繰り返し参照キーは、対応する個別の値である辞書に各データフレームを保存を使用することを検討してください:

import sqlite3 
import pandas as pd 

conn = sqlite3.connect('my_db.db') 
c = conn.cursor() 

dfDict = {} 
for entry in c.execute("SELECT DISTINCT A FROM table"): 
    strSQL = "SELECT * FROM table WHERE A = :nameofparam" 
    dfDict[entry[0]] = pd.read_sql(strSQL, conn, params={'nameofparam': entry[0]}) 

c.close() 
conn.close() 

for k, v in dfDict.items(): 
    print(k, '\n', v.head()) 
+0

通常のSQLクエリでは、 "?"を使用することが重要です。 SQL攻撃から保護します。上記のコードは安全ですか? pd.read_sql()はコードを実行できますか? – deltap

+0

カーソル値をSQL文にバインドされた名前付きパラメータに渡す 'read_sql'のparams引数を使用して更新を参照してください。これはSQLインジェクションから保護します。 – Parfait