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

如何在Pandas中行向合并两个DataFrame并标记数据来源?

Pandas 实现指定规则的DataFrame行合并

需求说明

现有两个DataFrame:df1和df2,需按以下规则行向合并:

  • 当行在两个DataFrame中同时存在(匹配altshortname、Code、Type三个字段),保留df1的数据,并为该行的alt列赋值1;
  • 仅来自df1的行,common列值为1;
  • 仅来自df2的行,alt列值为1。

解决方案

方法一:外连接合并后处理列

利用merge外连接合并数据集,再通过列值填充调整得到目标结果,适合数据量较大的场景:

import pandas as pd

# 定义df1(修正原数据语法错误)
data1 = {
    'commonshortname': ['SNX.US', '002400.CH', 'CDW.US', 'CEC.GR', '300002.CH'],
    'altshortname': ['SNX.US', '002400.SHE', 'CDW.US', 'CEC.XETRA', '300002.SHE'],
    'Code': ['SNX', '002400', 'CDW', 'CEC', '300002'],
    'Type': ['Common Stock'] * 5,
    'common': [1] * 5
}
df1 = pd.DataFrame(data1)

# 定义df2
data2 = {
    'altshortname': ['SEDG.US', 'MHLD.US', 'CDW.US', 'POLA.US', 'PHASQ.US'],
    'Code': ['SEDG', 'MHLD', 'CDW', 'POLA', 'PHASQ'],
    'Type': ['Common Stock'] * 5,
    'alt': [1] * 5
}
df2 = pd.DataFrame(data2)

# 按指定字段外连接合并
merged = pd.merge(df1, df2, on=['altshortname', 'Code', 'Type'], how='outer')

# 调整列值:仅保留符合规则的标记,其余设为空
merged['common'] = merged['common'].fillna(pd.NA)
merged['alt'] = merged['alt'].fillna(pd.NA)

# 调整列顺序为需求格式
result = merged[['commonshortname', 'altshortname', 'Code', 'Type', 'common', 'alt']]
print(result)

方法二:合并后分组处理

先合并所有行,再按匹配字段分组,对每组数据按规则筛选,逻辑更直观,便于自定义扩展:

import pandas as pd

# 定义df1和df2(同方法一)
data1 = {
    'commonshortname': ['SNX.US', '002400.CH', 'CDW.US', 'CEC.GR', '300002.CH'],
    'altshortname': ['SNX.US', '002400.SHE', 'CDW.US', 'CEC.XETRA', '300002.SHE'],
    'Code': ['SNX', '002400', 'CDW', 'CEC', '300002'],
    'Type': ['Common Stock'] * 5,
    'common': [1] * 5
}
df1 = pd.DataFrame(data1)

data2 = {
    'altshortname': ['SEDG.US', 'MHLD.US', 'CDW.US', 'POLA.US', 'PHASQ.US'],
    'Code': ['SEDG', 'MHLD', 'CDW', 'POLA', 'PHASQ'],
    'Type': ['Common Stock'] * 5,
    'alt': [1] * 5
}
df2 = pd.DataFrame(data2)

# 给df2添加缺失的commonshortname列,保证列结构一致
df2['commonshortname'] = pd.NA

# 合并所有行并重置索引
combined = pd.concat([df1, df2], ignore_index=True)

# 定义分组处理函数
def process_group(group):
    has_df1 = group['common'].notna().any()
    has_df2 = group['alt'].notna().any()
    
    if has_df1 and has_df2:
        # 交集行:保留df1数据并设置alt=1
        df1_row = group[group['common'] == 1].iloc[0].copy()
        df1_row['alt'] = 1
        return pd.DataFrame([df1_row])
    elif has_df1:
        # 仅df1的行:直接保留
        return group[group['common'] == 1]
    else:
        # 仅df2的行:直接保留
        return group[group['alt'] == 1]

# 分组处理并清理索引
result = combined.groupby(['altshortname', 'Code', 'Type'], as_index=False).apply(process_group).reset_index(drop=True)
print(result)

结果说明

两种方法均可生成符合需求的结果,可根据数据规模和扩展需求选择使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:12:43