2017-11-22 3 views
1

をグループ化する新しい列を生成:私がやりたいことは3つの新しい列(total_buy、total_sellとtotal_operationsある私は次のような形式で自分のデータフレーム内の新しい列を実装しようとしているデータフレーム

Client_id Product_a 

1   1 

1   2 

1   1 

1   0 

2   1 

2   0 

2   3 

2   1 

だから... ... )。これらの新しい列では、各client_idの購入、売り、合計の合計額を計算したいと考えています。各client_idは、少なくとも1回、最大24回表に表示されます。 だから私の出力は、(サンプルは上記示したため)、次のようになります。

Client_id A_buy A_sell A_operations 

1   2  2  4 
2   4  3  7 

私は合計/平均/最小/最大、彼らのような異なる機能をGROUPBYを使用していた非常に便利ですが、今私がしたいのですがこの新しいアプローチを試してみてください。実際に私は約52kのクライアントと12種類の製品を持っていますが、私はこの新しい作業にどのようにアプローチするのか分かりません。 私のデータフレームの行の合計は約600kで、各クライアントは少なくとも1つのオカレンスと最大24個(私は2年間のデータを持っています)

このタスクにはどのような組み込み関数がありますか? この問題を解決するためのアドバイスはありますか?

アドバイスをいただきありがとうございます!

+0

'Product_a'と' A_buy'、 'A_sell'と' A_operations'の関係は何ですか? – unutbu

+0

同じid_clientを持つ各行について、各月のproduct_aの最終的な金額を示しています。元の投稿のサンプルに続いてclient_id = 1の場合、購入した次の月に1製品を購入した最初の月別の1つは、第3月に彼は1つの製品を販売し、先月に別のものを販売しました。ですから、client_id = 1は2回購入して2回、client_id = 2には同じロジックを販売しました。問題を明確にしたいと思います。 – WinterZ

+0

投稿したDataFrameには、 'Client_id'と' Product_a'カラムしかありません。月を知り、彼が商品を買ったり売ったりしたことはどうですか? – unutbu

答えて

2

のは、このような何かを試してみましょう:

df = pd.DataFrame({'Client_id':[1,1,1,1,2,2,2,2],'Product_a':[1,2,1,0,1,0,3,1]}) 

#Define action based on diff previous record fill first record with first value in group 
df_out = df.assign(action=df.groupby('Client_id')['Product_a']\ 
          .apply(lambda x: x.diff().fillna(x.iloc[0]))) 

#Classify buy or sell based of positive or negative action 
df_out['buys'] = np.where(df_out.action.gt(0), df_out.action, 0) 
df_out['sells'] = np.where(df_out.action.lt(0), df_out.action.mul(-1), 0) 

#Lastly, groupby and sum records by client 
df_out.groupby('Client_id')[['buys', 'sells']].sum().eval('operations = buys + sells')\ 
     .add_prefix('A_').reset_index() 

出力:

Client_id A_buys A_sells A_operations 
0   1  2.0  2.0   4.0 
1   2  4.0  3.0   7.0 
+1

@WinterZを使用してテーブルをグループ化しました。この回答があなたを助けたら、あなたは[同意する](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work?answertab=votes#tab-top)ですか?私は本当にそれを感謝します。 –

+0

私は、この作業のための1つのソリューションを開発しました。これは、データセットの形式の性質のためにパンダを使用していました。あなたのソリューションは非常にうまく動作し、タスクを非常にうまく解決しますが、シフト方式のpandasはかなり速くなります。 – WinterZ

+0

@WinterZここのコメントにdiffを使用してソリューションを貼り付けても構いません。私はあなたが何を使い終わったかを見たいと思っています。ありがとうございました。 –

0

は私のパンダのコードは、いくつかの簡単なフィルタや私のデータベース内のすべての製品のシリアル化を使用して動作します...誰かがする必要がある場合単純な列でのみ使用すると、forループは必要ありません。列名のstr(製品)を変更してください。

for product in productos: 
dfloop[str(product) + '_buys'] = dfloop[product] 
dfloop[str(product) + '_sells'] = 0 

dfloop.loc[dfloop["id_cliente"] == dfloop["id_cliente"].shift(1),[str(product) + '_buys']] \ 
    = dfloop[product] - dfloop[product].shift(1) 

dfloop.loc[dfloop[str(product) + '_buys'] < 0 ,[str(product) + '_sells']] = -dfloop[str(product) + '_buys'] 
dfloop.loc[dfloop[str(product) + '_buys'] < 0 ,[str(product) + '_buys']] = 0 

コードは、非常に単純なすべてのイムの最初に新品を作るとidの変更がある場合、私はチェックのための最初の...パンダからシフト機能を使用して、私のDB内の各製品の列を販売し、行の間に積の差を置く。

最後の2行のコードは、購入額と売り上げの合計を正しく再計算するだけです。これは、いくつかの変更だけで任意のdbのために正しく動作します。 私はこのコードが今後誰かを助けることを願っています。

関連する問題