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

在R中实现按条件将df2单元格值求和至df1的函数方法

解决方案

核心思路

先对df2按指定的条件列分组,对需要求和的列计算分组总和;再将分组结果与df1按条件列合并,最后把df1原列和分组求和的对应列相加,得到最终合并后的DataFrame。

代码实现

导入pandas库后,直接定义复用性强的函数:

import pandas as pd

def merge_and_sum(df1, df2, group_columns, sum_columns):
    # 对df2按条件列分组求和,条件组合唯一所以每组仅一行结果
    df2_grouped = df2.groupby(group_columns)[sum_columns].sum().reset_index()
    # 左连接合并df1和分组结果,保留df1所有行
    merged_df = df1.merge(df2_grouped, on=group_columns, how='left', suffixes=('', '_sum'))
    # 遍历求和列,将原列与分组求和列相加(缺失值转0避免计算出错)
    for col in sum_columns:
        merged_df[col] = merged_df[col].fillna(0) + merged_df[f'{col}_sum'].fillna(0)
        merged_df.drop(f'{col}_sum', axis=1, inplace=True)
    # 恢复原df1的列顺序
    merged_df = merged_df[df1.columns]
    return merged_df

示例测试

用你提供的示例数据验证:

# 构造示例df1
df1 = pd.DataFrame({
    'x1': [1, 2, 3, pd.NA, 7],
    'x2': [5, 6, 7, 8, 4],
    'x3': [1100, 2100, 1100, 2100, 3100],
    'x4': [2016, 2016, 2017, 2017, 2017],
    'x5': ['string1', 'string2', 'string3', 'string4', 'string5']
})

# 构造示例df2
df2 = pd.DataFrame({
    'x1': [3, 4, 2, 1],
    'x2': [pd.NA, 8, 5, 7],
    'x3': [1100, 2100, 1100, 2100],
    'x4': [2017, 2017, 2016, 2016],
    'x5': ['string3', 'string4', 'string1', 'string2']
})

# 指定条件列和需要求和的列
group_cols = ['x3', 'x4', 'x5']
sum_cols = ['x1', 'x2']

# 调用函数生成目标结果
new_df1 = merge_and_sum(df1, df2, group_cols, sum_cols)
print(new_df1)

运行输出和示例完全一致:

x1    x2    x3    x4       x5
0  3.0  10.0  1100  2016  string1
1  3.0  13.0  2100  2016  string2
2  6.0   7.0  1100  2017  string3
3  4.0   8.0  2100  2017  string4
4  7.0   4.0  3100  2017  string5

关键细节说明

  • 分组求和:因为条件组合唯一,groupby+sum会直接生成每个条件对应的唯一求和结果,不会有重复行。
  • 左连接合并:保证df1中所有行都被保留,哪怕df2里没有对应条件的记录(比如示例中x3=3100的行)。
  • 缺失值处理:用fillna(0)把NA转为0,避免求和时出现无效的NA值。
  • 列顺序恢复:最后按df1原列顺序重排,确保输出结果的列结构和输入完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:40:40