是否存在灵活的group by函数?如何实现目标DataFrame聚合结果?
问题解答
原始数据
| Name_A | Name_B | A | B | Type_A | Type_B |
|---|---|---|---|---|---|
| Test | Test | 5 | 5 | Game | Game |
| nan | Test | nan | 5 | nan | Game |
| nan | Test | nan | 10 | nan | Game |
错误代码及输出结果
你执行的代码:
DF.groupby(['Name_A',"Type_A"], as_index=False)[['A','B']].sum() NewDF = DF.where(DF['TypeA']== "Game")
得到的结果:
| Name_A | Name_B | A | B | Type_A | Type_B |
|---|---|---|---|---|---|
| Test | nan | 5 | 5 | Game | Game |
期望结果
| Name_A | Name_B | A | B | Type_A | Type_B |
|---|---|---|---|---|---|
| Test | Test | 5 | 20 | Game | Game |
解决方案
完全可以实现目标,不需要用merge,调整groupby的逻辑就行。原代码的问题在于:
- 分组键选了
Name_A和Type_A,但这两列有大量空值,导致后两行无法和第一行归为同一组; where语句里的列名写错了(应该是Type_A而非TypeA)。
方法一:先填充空值再聚合
先把Name_A和Type_A的空值用同组(按Name_B+Type_B)的非空值填充,确保所有行的分组键一致,再做聚合:
# 按Name_B和Type_B分组,用组内非空值填充空列 filled_df = DF.groupby(['Name_B', 'Type_B'], group_keys=False).apply(lambda x: x.ffill().bfill()) # 按完整字段分组,对A取第一个非空值、对B求和 result_df = filled_df.groupby(['Name_A', 'Name_B', 'Type_A', 'Type_B'], as_index=False).agg( A=('A', 'first'), B=('B', 'sum') )
方法二:直接按有效分组键聚合后补全字段
如果确认Name_B+Type_B的组合唯一对应Name_A和Type_A的有效值,可以直接按这两个字段聚合,再手动补全其他字段:
# 按Name_B和Type_B分组,对A取非空值、对B求和 result_df = DF.groupby(['Name_B', 'Type_B'], as_index=False).agg( A=('A', 'max'), # 取唯一非空值,用sum也可以 B=('B', 'sum') ) # 补全Name_A和Type_A的有效值 result_df['Name_A'] = 'Test' result_df['Type_A'] = 'Game' # 调整列顺序到期望的格式 result_df = result_df[['Name_A', 'Name_B', 'A', 'B', 'Type_A', 'Type_B']]
两种方法都能得到你想要的结果。
内容的提问来源于stack exchange,提问作者TourEiffel
相关产品推荐
相关产品推荐

