如何合并多个Pandas DataFrame并按指定列分组将同列值转为数组
实现方法
你之前觉得merge、concat不适用是因为单独使用这两个接口只能完成基础拼接/关联,搭配分组聚合操作就能实现你的需求,具体实现分两种场景:
场景1:仅收集所有匹配值为列表,不要求对应原始df顺序
如果不需要严格对齐每个输入df的位置,只要把同分组下的所有值合并为列表,实现逻辑最简单:
import pandas as pd # 构造示例数据 df1 = pd.DataFrame({'A': ['x', 'y'], 'Value': [0, 0]}) df2 = pd.DataFrame({'A': ['x', 'y', 'z'], 'Value': [1, 1, 1]}) # 第一步:拼接所有待合并的DataFrame all_df = pd.concat([df1, df2], ignore_index=True) # 第二步:按指定列分组,将目标列聚合为列表 result = all_df.groupby('A', as_index=False)['Value'].agg(list).rename(columns={'Value': 'Number_Value'})
输出结果:
| A | Number_Value |
|---|---|
| x | [0, 1] |
| y | [0, 1] |
| z | [1] |
场景2:严格对齐每个原始df的位置,无匹配值留空
如果要实现你示例中z对应[, 1]的效果(第一个df无匹配值留空,第二个df有值则填),需要先给每个df加来源标记,透视为宽表后再合并为列表:
import pandas as pd import numpy as np df1 = pd.DataFrame({'A': ['x', 'y'], 'Value': [0, 0]}) df2 = pd.DataFrame({'A': ['x', 'y', 'z'], 'Value': [1, 1, 1]}) dfs = [df1, df2] # 给每个df加来源标记 for idx, df in enumerate(dfs): df['source'] = idx all_df = pd.concat(dfs, ignore_index=True) # 透视为宽表,每个来源的df对应一列,无匹配值自动填充NaN pivot_df = all_df.pivot(index='A', columns='source', values='Value').reset_index() # 可选:把NaN替换为空字符串,和示例输出的空占位一致 pivot_df = pivot_df.fillna('') # 将多列合并为列表 pivot_df['Number_Value'] = pivot_df[[0,1]].values.tolist() # 提取最终需要的列 result = pivot_df[['A', 'Number_Value']]
输出结果:
| A | Number_Value |
|---|---|
| x | [0, 1] |
| y | [0, 1] |
| z | ['', 1] |
扩展说明
如果有超过2个DataFrame需要合并,直接把待合并的df放到concat的输入列表即可;如果需要按多列匹配、聚合多列,修改groupby的分组列和agg的聚合规则即可。
内容的提问来源于stack exchange,提问作者user17085455
相关产品推荐
相关产品推荐

