You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame中按相同ID合并多行至单行的实现方案

问题描述

现有如下DataFrame:

ID     Qnt  Rec value
AB1234  20   1   2
xy123   30   1   5
xy123   30   2   2

需求:按ID分组,将相同ID的行合并为单行,计算Qnt、所有Rec、所有Value列值的乘积(例如ID xy123的计算式为 30*1*5*2*2 = 600),输出格式如下:

ID     Qnt  Rec Value Rec   Value  output
AB1234  20   1    2   Null  Null     40
xy123   30   1    5    2      2      600

当前实现方式是将DataFrame按Rec拆分为两部分后合并,现寻求其他灵活的可行方案(后续对输出格式有调整需求)。


方案1:GroupBy + 自定义聚合函数

通过groupby('ID')对每个分组单独处理列展开与乘积计算,灵活性强,适配后续格式调整:

import pandas as pd

# 构造原始数据
df = pd.DataFrame({
    'ID': ['AB1234', 'xy123', 'xy123'],
    'Qnt': [20, 30, 30],
    'Rec': [1, 1, 2],
    'value': [2, 5, 2]
})

def process_group(group):
    # 提取Qnt(*假设同一ID的Qnt值一致,取第一个即可*)
    qnt = group['Qnt'].iloc[0]
    # 提取当前分组的所有Rec和value值
    rec_list = group['Rec'].tolist()
    value_list = group['value'].tolist()
    # 计算总乘积:Qnt × 所有Rec的乘积 × 所有value的乘积
    total_product = qnt * pd.Series(rec_list).prod() * pd.Series(value_list).prod()
    # 构造结果行,缺省值补Null
    result_row = {
        'ID': group.name,
        'Qnt': qnt,
        'Rec_1': rec_list[0] if len(rec_list) >= 1 else None,
        'Value_1': value_list[0] if len(value_list) >= 1 else None,
        'Rec_2': rec_list[1] if len(rec_list) >= 2 else None,
        'Value_2': value_list[1] if len(value_list) >= 2 else None,
        'output': total_product
    }
    return pd.Series(result_row)

# 应用分组处理并重置索引
result_df = df.groupby('ID').apply(process_group).reset_index(drop=True)
# 重命名列以匹配期望输出格式
result_df.columns = ['ID', 'Qnt', 'Rec', 'Value', 'Rec', 'Value', 'output']
print(result_df)

如果后续需要支持更多Rec条目,只需修改process_group中结果行的列构造逻辑即可。


方案2:Pivot 重塑宽表后计算

利用pivot将Rec转为列索引,把Rec和value分别转成宽表,再合并计算乘积,适合Rec取值为连续整数的场景:

import pandas as pd

df = pd.DataFrame({
    'ID': ['AB1234', 'xy123', 'xy123'],
    'Qnt': [20, 30, 30],
    'Rec': [1, 1, 2],
    'value': [2, 5, 2]
})

# 将Rec列转为宽表
rec_wide = df.pivot(index='ID', columns='Rec', values='Rec').add_prefix('Rec_')
# 将value列转为宽表
value_wide = df.pivot(index='ID', columns='Rec', values='value').add_prefix('Value_')
# 提取每个ID对应的Qnt值(取第一个)
qnt_df = df.groupby('ID')['Qnt'].first().reset_index()

# 合并所有数据
merged_df = qnt_df.merge(rec_wide, on='ID').merge(value_wide, on='ID')
# 计算总乘积
merged_df['output'] = merged_df['Qnt'] * merged_df.filter(like='Rec_').prod(axis=1) * merged_df.filter(like='Value_').prod(axis=1)
# 调整列名与顺序以匹配需求
merged_df.columns = ['ID', 'Qnt', 'Rec', 'Rec', 'Value', 'Value', 'output']
merged_df = merged_df[['ID', 'Qnt', 'Rec', 'Value', 'Rec', 'Value', 'output']]
print(merged_df)

后续如果新增Rec条目,pivot会自动生成对应列,无需手动修改列构造逻辑。


内容的提问来源于stack exchange,提问作者arawind73

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 17:33:32