首页 > 解决方案 > 根据 ID 和月份聚合数据,具体取决于另一列(前与后)

问题描述

假设 python 中的以下数据框,我如何检查每个名称的pre_hit_pricepost_hit_price(平均值或总和)?

(在 SAS 中,我们可以使用 first. and last. 来解决这个问题)

d = {'Name': ['A','A','A','A','B','B','B','B'], 'price' : [0,1,2,3,2,4,6,8] , 'month': [201901, 201902, 201903, 201904, 201901, 201902, 201903, 201904] , 'hit': [0,1,0,0,0,1,1,0]}
df = pd.DataFrame(data=d)
df

示例_df:

在此处输入图像描述

输出_df:

在此处输入图像描述

标签: pythonpandasdataframeaggregate

解决方案


方法一

使用GroupBy.sum+ DataFrame.unstack。将布尔级数归为组 ( groupby_hit) 的方法在方法 2中进行了说明。你只需要添加使用Series.map

groupby_hit=df.groupby('Name').hit.cumsum().eq(0).map({False:'post_hit_price',True:'pre_hit_price'})
new_df=df.groupby(['Name',groupby_hit],sort=False).price.sum().unstack().rename_axis(columns=None)
print(new_df)

      pre_hit_price  post_hit_price
Name                               
A                 0               6
B                 2              18

方法二

根据列中的外观和使用with1的列hit值创建两个 DataFrame以执行 a (请参阅详细信息)。然后使用+ :NameDataFrame.groupby.cumsumSeries.eqboolean indexingGroupby.aggpd.concat

prehit_mask=df.groupby('Name').hit.cumsum().eq(0)
df_pre=df[prehit_mask]
df_post=df[~prehit_mask]
new_df=pd.concat([df_pre.groupby('Name').price.agg(pre_hit_price='sum'),
                  df_post.groupby('Name').price.agg(post_hit_price='sum')],
                  axis=1)
print(new_df)

      pre_hit_price  post_hit_price
Name                               
A                 0               6
B                 2              18

如果您使用熊猫 <0.25.0

new_df=pd.concat([df_pre.groupby('Name').price.agg({'pre_hit_price':'sum'}),
                  df_post.groupby('Name').price.agg({'post_hit_price':'sum'})],
                  axis=1)

细节:

print(prehit_mask)

0     True
1    False
2    False
3    False
4     True
5    False
6    False
7    False
Name: hit, dtype: bool

推荐阅读