获取分组DataFrame的累计和并合并不同行的关联信息
问题解决思路
原始数据
import numpy as np import pandas as pd data1 = { 'Product': ['Product1', 'Product2', 'Product3', 'Product1', 'Product1', 'Product1','Product1', 'Product4', 'Product5', 'Product6'], 'Name': ['Bayer', 'Sanofi', 'Pfizer', 'Bayer', 'Bayer', 'Bayer' ,'AstraZeneca', 'Company1', 'Company2', 'Company2'], 'Region': ['Europe', 'Europe', 'Asia', np.nan, np.nan, np.nan, np.nan, 'Asia', np.nan, np.nan], 'Country': ['France', np.nan, np.nan, np.nan, np.nan, np.nan, 'India', 'Indonesia', np.nan, np.nan], 'Amount': [910, 200, 898, 12, 50, 13, 52, 250,260,270], } df1 = pd.DataFrame(data1)
需求说明
按Product和Name分组,计算每组Amount的累计总额;每个Product-Name组合仅保留一行,同时整合该组合下Region和Country的非空信息。
当前问题
使用transform(pd.Series.cumsum)会保留所有行,无法满足单组单行的要求,且无法处理非数值类型的非空信息整合。
期望输出
Product Name Region Country Amount Cumsum orders 0 Product1 Bayer Europe France 13 985 6 Product1 AstraZeneca NaN India 52 52 1 Product2 Sanofi Europe NaN 200 200 2 Product3 Pfizer Asia NaN 898 898 7 Product4 Company1 Asia Indonesia 250 250 8 Product5 Company2 NaN NaN 260 260 9 Product6 Company2 NaN NaN 270 270
解决方案
通过groupby结合自定义聚合函数实现,针对不同列设置不同聚合逻辑:
def get_first_non_null(series): non_null_vals = series.dropna() return non_null_vals.iloc[0] if not non_null_vals.empty else np.nan # 分组聚合 result_df = df1.groupby(['Product', 'Name'], as_index=False).agg( Region=('Region', get_first_non_null), Country=('Country', get_first_non_null), Amount=('Amount', 'last'), # 取每组最后一行的Amount值,匹配示例展示 Cumsum_orders=('Amount', 'sum') # 组内总额就是累计到最后一行的和 ) # 调整列顺序与期望输出一致 result_df = result_df[['Product', 'Name', 'Region', 'Country', 'Amount', 'Cumsum_orders']] print(result_df)
逻辑说明
get_first_non_null:提取每组中Region/Country的第一个非空值,完成信息整合Amount用last取组内最后一行数值,对应示例中的展示形式Cumsum_orders直接用sum计算组内总额,等价于累计到最后一行的结果as_index=False保证分组键保留为列,维持DataFrame结构
内容的提问来源于stack exchange,提问作者Paul G.
相关产品推荐
相关产品推荐

