2017-10-17 7 views
0

私は(マーキングパフォーマンスベンチのテストを実行している)として、以下のシナリオを持っている:することはできません再利用パンダジェネレータオブジェクト

def read_sql_query(query, chunk_size, cnxn): 
    try: 
     df = pd.read_sql_query(query, cnxn, index_col=['product_key'], chunksize=100000) 
     return df 
    except Exception as e: 
     print(e) 

def return_chunks_in_df(df, start_date, end_date): 
    try: 

     sub_df = pd.DataFrame() 
     for chunks in df:    
      sub_df = pd.concat([sub_df, chunks.loc[(chunks['trans_date'] > start_date) & (chunks['trans_date'] < end_date)]], ignore_index=True) 
     print(sub_df.info()) 
     return sub_df  
    except Exception as e: 
     print(e) 

query = r"select * from sales_rollup where product_key in (select product_key from temp limit 10000)" 

start_time = timeit.default_timer() 
df = read_sql_query(query, 100000, cnxn) 
print(df) 
print('time to chunk:' + str(timeit.default_timer() - start_time)) 

#scenario 1 
start_time = timeit.default_timer() 
sub_df1 = return_chunks_in_df(df, '2015-01-01', '2016-01-01') 
print('scenario1:' + str(timeit.default_timer() - start_time)) 

#scenario 2  
start_time = timeit.default_timer() 
sub_df2 = return_chunks_in_df(df, '2016-01-01', '2016-12-31') 
print('scenario2:' + str(timeit.default_timer() - start_time)) 

私が午前問題は、データフレームは、常に0の行をたとえ返しシナリオ2でありますフィルタリングされた日付範囲のデータがあります。私は(DFをループしようとした)が、以下のループが実行されることはありません:

for chunks in df: 
    print(chunks.info()) 

私は、私はちょうど実行前に以下のように再びDFを再作成する場合、結果はシナリオ2のために設定を取得することができる午前:

df = read_sql_query(query, 100000, cnxn) 

シナリオを実行する最初のコアの問題は、常に2番目のシナリオではない値を返します。 dfオブジェクトは最初の実行後に何とか失効しますか? ヘルプ/ポインターを高く評価しました。

+0

ダウン投票で何理由を述べることなく? – Abhi

答えて

1

発電のための正しいのparamを提供することができない理由を見つける必要がある:

def gen(n): 
    for i in range(n): 
     yield i 

In [11]: g = gen(3) 

In [12]: list(g) 
Out[12]: [0, 1, 2] 

In [13]: list(g) 
Out[13]: [] 

あなたは両方にチャンクを渡すことができるようにリファクタリング可能性があり、それらを再利用するためには:

def concat_chunk(acc, chunk, start_date, end_date): 
    return pd.concat([acc, chunk.loc[(chunk['trans_date'] > start_date) & (chunk['trans_date'] < end_date)]], ignore_index=True) 

sub_df1 = pd.DataFrame() 
sub_df2 = pd.DataFrame() 
for chunk in df: 
    sub_df1 = concat_chunk(sub_df1, chunk, '2015-01-01', '2016-01-01') 
    sub_df2 = concat_chunk(sub_df2, chunk, '2016-01-01', '2016-12-31') 

注:この方法は、あなたのティムをオフにスローされます、それを配布イングス...


また、SQLにwhereロジックを移動することを好むことがあります。

query = r"""select * from sales_rollup 
      where product_key in (select product_key from temp limit 10000) 
      and '2015-01-01' < trans_date 
      and trans_date < '2016-01-01'""" 

そのように、おそらくあなたはチャンクの必要がありませんよ!一般的に


、「発電機を再利用」する方法はただそれリスト作りです...しかし、それは通常、(断片的にそれを構築する)ポイントを敗北:

chunks = list(df) # Note chunks is probably a more descriptive name... 
0
sub_df = pd.DataFrame() 
for chunks in df:    
    sub_df = pd.concat([sub_df, ... 
print(sub_df.info()) 
return sub_df  

なぜsub_dfを2回設定するか分かりません。最初の設定は無効になります。

この種の問題を理解するには、逆の考えが必要です。静的なアイテムではなく、変数によって

sub_df = pd.concat([sub_df, ... 

フィードパラメータ: 最初のuは一つのコマンドを実行する必要があります。

、これは問題ありません場合は、uが通って第1の実行後に「使い切る」されているウル元のプログラムがpd.concat

+0

もしそれが有用であれば私に教えてください^ _^ –

+0

こんにちはZhen、迅速な応答のおかげで。私はsub_dfを2回設定するあなたのコメントを理解していませんでした。最初のインスタンスはデータフレームを宣言していないため、私は連結できません。 – Abhi

関連する問題