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

如何基于至少一列匹配合并Pandas DataFrame记录并保留非空字段?

合并DataFrame中关联记录(优先保留非空字段)

你需要合并存在至少一列匹配的记录,优先保留已填充的非空字段,最终得到每个唯一组的完整记录。以下是基于pandas的实现方案:

步骤1:导入依赖并构造DataFrame

先把原始数据转换成pandas的DataFrame,并将空字符串替换为缺失值(NaN),方便后续处理:

import pandas as pd
import numpy as np

# 构造原始数据
data = {
    'id': ['10352897', '10352897', '10352897', '10352897', '', '', '', '23578910', '23578910', '23578910', '23578910', '', '', ''],
    'phone': ['', '10225967', '', '10225967', '10225967', '10225967', '', '', '38256789', '', '38256789', '38256789', '38256789', ''],
    'email': ['', '', 'user@gmail.com', 'user@gmail.com', '', 'user@gmail.com', 'user@gmail.com', '', '', 'user2@gmail.com', 'user2@gmail.com', '', 'user2@gmail.com', 'user2@gmail.com']
}

df = pd.DataFrame(data)
# 将空字符串转为NaN
df = df.replace('', np.nan)

步骤2:合并关联记录

这里提供两种可行的方法:

方法一:分组填充缺失值后去重

通过按email、phone、id依次分组填充缺失值,确保同一组的记录都拥有完整的字段值,最后去重得到结果:

# 按email分组,填充id和phone的缺失值
df['id'] = df.groupby('email')['id'].transform(lambda x: x.bfill().ffill())
df['phone'] = df.groupby('email')['phone'].transform(lambda x: x.bfill().ffill())

# 按phone分组,填充id和email的缺失值
df['id'] = df.groupby('phone')['id'].transform(lambda x: x.bfill().ffill())
df['email'] = df.groupby('phone')['email'].transform(lambda x: x.bfill().ffill())

# 按id分组,填充phone和email的缺失值
df['phone'] = df.groupby('id')['phone'].transform(lambda x: x.bfill().ffill())
df['email'] = df.groupby('id')['email'].transform(lambda x: x.bfill().ffill())

# 去重并重置索引
result = df.drop_duplicates().reset_index(drop=True)

方法二:基于分组键聚合

为每条记录生成分组键(优先使用id,其次phone,最后email),然后按分组键聚合,取每个字段的第一个非空值:

# 生成分组键
def get_group_key(row):
    if pd.notna(row['id']):
        return row['id']
    elif pd.notna(row['phone']):
        return row['phone']
    else:
        return row['email']

df['group_key'] = df.apply(get_group_key, axis=1)

# 分组聚合,提取每个字段的非空值
result = df.groupby('group_key').agg(
    id=('id', lambda x: x.dropna().iloc[0]),
    phone=('phone', lambda x: x.dropna().iloc[0]),
    email=('email', lambda x: x.dropna().iloc[0])
).reset_index(drop=True)

最终输出

执行上述代码后,result就是你需要的结果:

id      phone           email
0  10352897  10225967  user@gmail.com
1  23578910  38256789  user2@gmail.com

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:50:24