如何用Pandas分别合并两个DataFrame的左右部分并累加同名用户数据?
问题描述
现有两个结构相同的DataFrame,均包含左右两部分(以Nan列为分隔):
第一个DataFrame
| names | val1 | val2 | Nan | names | val1 | val2 |
|---|---|---|---|---|---|---|
| user1 | 1 | 2 | Nan | user3 | 3 | 4 |
| user2 | 2 | 3 | Nan | user1 | 3 | 3 |
第二个DataFrame
| names | val1 | val2 | Nan | names | val1 | val2 |
|---|---|---|---|---|---|---|
| user1 | 3 | 2 | Nan | user4 | 2 | 1 |
| user2 | 5 | 3 | Nan | user1 | 1 | 5 |
需要实现的合并规则:
- 按
names列匹配,同名用户的val1、val2值累加 - 需将
Nan列左侧部分与右侧部分分开合并 - 期望得到的结果如下:
期望合并结果
| names | val1 | val2 | Nan | names | val1 | val2 |
|---|---|---|---|---|---|---|
| user1 | 4 | 4 | Nan | user1 | 4 | 8 |
| user2 | 7 | 6 | Nan | user3 | 3 | 4 |
| Nan | user4 | 2 | 1 |
已知可以通过拆分每个DataFrame为左右两部分再分别合并实现,想了解是否有更简便的方法。
更简便的实现方法
不需要拆分DataFrame,可通过合并同区域数据后直接分组求和的方式,一次性完成左右两部分的累加合并,步骤如下:
1. 定义通用累加函数
先写一个复用函数,用来对任意一块(左/右)的names、val1、val2进行分组求和,并补全行结构:
import pandas as pd def aggregate_section(data): # 按names分组,对val1、val2求和 agg_result = data.groupby('names')[['val1', 'val2']].sum().reset_index() # 补全空行,匹配最终结果的行数要求 max_rows = max(len(df1), len(df2)) return agg_result.reindex(range(max_rows), fill_value='')
2. 分别处理左右区域
提取两个DataFrame的左、右区域数据,合并后调用函数完成累加:
# 构造示例DataFrame(注意原结构中重复列名会被自动重命名,这里用后缀区分) df1 = pd.DataFrame({ 'names': ['user1', 'user2'], 'val1': [1, 2], 'val2': [2, 3], 'Nan': ['Nan', 'Nan'], 'names_': ['user3', 'user1'], 'val1_': [3, 3], 'val2_': [4, 3] }) df2 = pd.DataFrame({ 'names': ['user1', 'user2'], 'val1': [3, 5], 'val2': [2, 3], 'Nan': ['Nan', 'Nan'], 'names_': ['user4', 'user1'], 'val1_': [2, 1], 'val2_': [1, 5] }) # 处理左侧区域 left_data = pd.concat([df1[['names', 'val1', 'val2']], df2[['names', 'val1', 'val2']]]) left_agg = aggregate_section(left_data) # 处理右侧区域 right_data = pd.concat([df1[['names_', 'val1_', 'val2_']], df2[['names_', 'val1_', 'val2_']]]) right_data.columns = ['names', 'val1', 'val2'] # 统一列名方便处理 right_agg = aggregate_section(right_data)
3. 拼接最终结果
将处理好的左右区域与Nan列拼接,补全空值后得到目标结构:
# 构造Nan列 nan_col = pd.DataFrame({'Nan': ['Nan'] * max(len(left_agg), len(right_agg))}) # 拼接所有部分 final_df = pd.concat([left_agg, nan_col, right_agg], axis=1) final_df = final_df.fillna('') print(final_df)
方法优势
- 避免了多次拆分合并的繁琐操作,逻辑更连贯
- 通用函数复用性强,后续结构调整时只需修改少量代码
- 最终结果完全匹配期望的格式与数值
内容的提问来源于stack exchange,提问作者Aries Ha
相关产品推荐
相关产品推荐

