[英]Pandas Conditional Rolling Sum of Two Columns
我在數據框中有四列,如下所示:
A B C D
75472 d1 x -36.0 0.0
75555 d2 x -38.0 0.0
75638 d3 x -18.0 0.0
75721 d4 x -18.0 1836.0
75804 d5 x 1151.0 0.0
75887 d6 x 734.0 0.0
75970 d7 x -723.0 0.0
我想有條件地對D
求和:
因此,對於上述情況, D 將是[-36, -74, -92, 1836, 2987, 3721, 2998]
。
我已經能夠使用 for 循環成功地做到這一點
for i, row in me.iterrows():
try:
if row['D'] > 0:
step1 = me.loc[(me['B'] == row['B']) & (me['A'] == row['A']), 'output'].iloc[0]
me_copy.iloc[i, me_copy.columns.get_loc('output')] = step1
else:
step1 = me.loc[(me['B'] == row['B']) & (me['A'] == (row['A'] - pd.DateOffset(days=1))), 'step1'].iloc[0]
receipts_adjustments_sales = me.loc[(me['B'] == row['B']) & (me['A'] == row['A']), 'C'].iloc[0]
me_copy.iloc[i, me_copy.columns.get_loc('output')] = step1 + receipts_adjustments_sales
except:
me_copy.iloc[i, me_copy.columns.get_loc('output')] = 0
但是 for 循環顯然非常昂貴,反模式並且基本上不會運行在我的整個數據幀上。 我正在嘗試復制 excel function 這里基本上已經寫在一組數據上,對於我的一生,我無法弄清楚如何做到這一點:
pd.Series.shift()
pd.Series.rolling()
我試圖用shift()
來做一段時間,但我意識到我必須為每一行創建一個單獨的列,這就是我使用 for 循環的原因。
泛化到組
df.loc[:, 'A_group'] = df.groupby(['A'])[df['D'] != 0].cumsum()
df.loc[:, 'E'] = df['D'].mask(df['D'] == 0).combine_first(df['C'])
df.loc[:, 'F'] = me.groupby(['A', 'A_group'])['E'].cumsum()
感謝斯科特波士頓的幫助!
這是一種方法:
grp = (df['D'] != 0).cumsum()
df['D_new'] = df['D'].mask(df['D'] == 0).combine_first(df['C']).groupby(grp).cumsum()
df
Output:
A B C D D_new
75472 d1 x -36.0 0.0 -36.0
75555 d2 x -38.0 0.0 -74.0
75638 d3 x -18.0 0.0 -92.0
75721 d4 x -18.0 1836.0 1836.0
75804 d5 x 1151.0 0.0 2987.0
75887 d6 x 734.0 0.0 3721.0
75970 d7 x -723.0 0.0 2998.0
創建 grps 來幫助 cumsum。 每個組都定義為 'D' 中出現的值,因此您在之前停止 cumsum 並選擇 D 的值並繼續 cumsum 直到 'D' 的下一個值
grp = (df['D'] != 0).cumsum()
Output:
A B C D D_new grp
75472 d1 x -36.0 0.0 -36.0 0
75555 d2 x -38.0 0.0 -74.0 0
75638 d3 x -18.0 0.0 -92.0 0
75721 d4 x -18.0 1836.0 1836.0 1
75804 d5 x 1151.0 0.0 2987.0 1
75887 d6 x 734.0 0.0 3721.0 1
75970 d7 x -723.0 0.0 2998.0 1
現在,當 D 具有非零數時,讓我們創建結合 'C' 和 'D' 的新列
df['newCD'] = df['D'].mask(df['D'] == 0).combine_first(df['C'])
Output:
A B C D D_new grp newCD
75472 d1 x -36.0 0.0 -36.0 0 -36.0
75555 d2 x -38.0 0.0 -74.0 0 -38.0
75638 d3 x -18.0 0.0 -92.0 0 -18.0
75721 d4 x -18.0 1836.0 1836.0 1 1836.0
75804 d5 x 1151.0 0.0 2987.0 1 1151.0
75887 d6 x 734.0 0.0 3721.0 1 734.0
75970 d7 x -723.0 0.0 2998.0 1 -723.0
最后,groupby 'grp' 和cumsum
newCD:
df['D_new_Details'] = df.groupby('grp')['newCD'].cumsum()
Output:
A B C D D_new grp newCD D_new_Details
75472 d1 x -36.0 0.0 -36.0 0 -36.0 -36.0
75555 d2 x -38.0 0.0 -74.0 0 -38.0 -74.0
75638 d3 x -18.0 0.0 -92.0 0 -18.0 -92.0
75721 d4 x -18.0 1836.0 1836.0 1 1836.0 1836.0
75804 d5 x 1151.0 0.0 2987.0 1 1151.0 2987.0
75887 d6 x 734.0 0.0 3721.0 1 734.0 3721.0
75970 d7 x -723.0 0.0 2998.0 1 -723.0 2998.0
另一個,類似於斯科特的回答:
groups = df['D'].ne(0).cumsum()
df['new'] = (df['C'].where(df['D'].eq(0), df['D'])
.groupby(groups)
.cumsum()
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.