You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Pandas中使用groupby时获取与聚合字段匹配的非聚合列?

如何在Pandas中使用groupby时获取与聚合字段匹配的非聚合列?

这个需求我之前也碰到过,其实核心就是找到每个分组中对应max(subid)的那一行,把它的reasonrecord和你的聚合结果关联起来就行,给你两种可行的方法:

方法一:先聚合,再关联匹配行(推荐,性能更优)

这种方法把聚合和匹配分开处理,逻辑清晰而且在数据量大的时候性能更好。

首先,先构造你的原始测试数据(方便你直接运行测试):

import pandas as pd

data = {
    'Id': [100, 100, 100, 101, 101],
    'application': ['app_1', 'app_2', 'app_3', 'app_1', 'app_2'],
    'is_a': [False, True, True, False, True],
    'is_b': [False, False, True, False, False],
    'is_c': [False, False, False, False, False],
    'reason': ['test1', 'test2', 'test3', 'test1', 'test2'],
    'subid': [4, 3, 5, 3, 4],
    'record': ['record100', 'record100', 'record100', 'record101', 'record101']
}
df = pd.DataFrame(data)

第一步,先完成你原本需要的聚合操作:

# 执行基础聚合,得到你已经有的结果
agg_df = df.groupby('Id').agg(
    application=('application', ', '.join),
    is_a=('is_a', 'max'),
    is_b=('is_b', 'max'),
    is_c=('is_c', 'max'),
    subid=('subid', 'max')
).reset_index()

第二步,找到每个Id分组中subid最大的那一行,提取对应的reasonrecord

# 用idxmax获取每个组中subid最大的行的索引,再提取需要的列
match_df = df.loc[df.groupby('Id')['subid'].idxmax(), ['Id', 'reason', 'record']]

第三步,把聚合结果和匹配到的列合并,就得到你想要的最终结果了:

# 按Id合并两个DataFrame
final_df = pd.merge(agg_df, match_df, on='Id', how='left')

运行后final_df就是你期望的输出格式啦。

方法二:分组时用自定义函数一次性处理

如果觉得分开写麻烦,也可以用自定义函数在分组时一次性完成所有操作,代码更紧凑,不过数据量大的时候性能会比方法一稍差:

def process_group(group):
    # 拼接application字段
    app_combined = ', '.join(group['application'])
    # 计算is_开头列的最大值
    is_a_max = group['is_a'].max()
    is_b_max = group['is_b'].max()
    is_c_max = group['is_c'].max()
    # 找到当前组中subid最大的行
    max_sub_row = group.loc[group['subid'].idxmax()]
    # 返回所有需要的字段
    return pd.Series({
        'application': app_combined,
        'is_a': is_a_max,
        'is_b': is_b_max,
        'is_c': is_c_max,
        'subid': max_sub_row['subid'],
        'reason': max_sub_row['reason'],
        'record': max_sub_row['record']
    })

# 应用自定义分组函数
final_df = df.groupby('Id').apply(process_group).reset_index()

小提醒

如果你的分组中存在多个行的subid都是最大值,idxmax会返回第一个出现的那一行的索引。如果需要处理这种多最大值的情况,可以根据你的需求调整逻辑(比如拼接所有对应的reason),不过看你的示例数据,每个组只有一个max subid的行,所以这个方法完全适用。

内容来源于stack exchange

火山引擎 最新活动