2017-05-26 247 views
1

認爲我有兩個pandas DataFrame S作爲如下,Python的大熊貓合併兩個DataFrames具有條件邏輯

df_actual

ID NAME PRODUCT CHANNEL ACTUAL 
1 A  W  G  233 
1 A  W  M  4 
1 A  X  G  188 
1 A  X  M  4 
1 A  Y  G  37 
1 A  Y  M  4 
1 A  Z  G  272 
1 A  Z  M  4 

df_target

ID NAME PRODUCT TARGET 
1 A  W  289 
1 A  X  253 
1 A  Y  36 
1 A  Z  334 

我期望得到的結果如下,

ID NAME PRODUCT CHANNEL ACTUAL TARGET 
1 A  W  G  233  284  <<< 289 * (233/(233+4)) 
1 A  W  G  4  5  <<< 289 * (4/(233+4)) 
1 A  X  G  188  248  <<< 253 * (188/(248+5)) 
1 A  X  G  4  5  <<< 253 * (4/(248+5)) 
1 A  Y  M  37  32  … 
1 A  Y  M  4  4  … 
1 A  Z  M  272  329  … 
1 A  Z  M  4  5  … 

所以基本上我想要做的,在df_actual中增加一個新列,名爲TARGET。爲了計算列TARGET內的值,

  1. 我得在df_actualACTUAL值一定IDNAMEPRODUCTCHANNEL,然後拿到TARGETdf_target爲同一IDNAMEPRODUCT
  2. 然後使用每個CHANNEL的貢獻與總CHANNEL某些IDNAMEPRODUCT計算每個CHANNELTARGET值。

例如,以獲得新的TARGETID 1,NAME A,PRODUCT W,和CHANNEL G,I需要使用此公式289 *(233 /(233 + 4))。

  • 289來自TARGETdf_target
  • 233來自對CHANNELģ
  • df_actualACTUAL
  • 4來自於CHANNEL中號
  • df_actualACTUAL

我的真實數據是相當龐大,超過1個百萬行。所以如果你能提出矢量化解決方案,我會非常感激。儘管如此,任何建議將不勝感激。謝謝。

回答

3

考慮以下量化方法:

In [39]: m = df_actual.merge(df_target) 

In [40]: m 
Out[40]: 
    ID NAME PRODUCT CHANNEL ACTUAL TARGET 
0 1 A  W  G  233  289 
1 1 A  W  M  4  289 
2 1 A  X  G  188  253 
3 1 A  X  M  4  253 
4 1 A  Y  G  37  36 
5 1 A  Y  M  4  36 
6 1 A  Z  G  272  334 
7 1 A  Z  M  4  334 

In [41]: m['TARGET'] = (m.TARGET * m.ACTUAL/m.groupby(['NAME','PRODUCT'])['ACTUAL'].transform('sum')).round() 

In [42]: m 
Out[42]: 
    ID NAME PRODUCT CHANNEL ACTUAL TARGET 
0 1 A  W  G  233 284.0 
1 1 A  W  M  4  5.0 
2 1 A  X  G  188 248.0 
3 1 A  X  M  4  5.0 
4 1 A  Y  G  37 32.0 
5 1 A  Y  M  4  4.0 
6 1 A  Z  G  272 329.0 
7 1 A  Z  M  4  5.0 
+0

很好的解決方案;) – jezrael

+0

@jezrael,謝謝:) – MaxU

+0

謝謝!這正是我正在尋找的。整潔,優雅,快速!再一次,非常感謝你! – arnold