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

如何对比DataFrame行:判断相等或df2空值转df1非空值

DataFrame行对比:特定匹配规则的实现

以下提供两种实现方式,满足你的需求:仅保留完全匹配或df2对应字段为空字符串且df1同字段非空、其余字段完全匹配的行ID,排除其他不匹配情况。

方案一:逐行转字典循环实现(小数据量友好)

逻辑直观,适合数据量不大的场景:

import pandas as pd

# 构造测试数据
df1 = pd.DataFrame({
    'NAME': ['Kelly', 'Jack', 'Josh'],
    'AGE': [15, 12, 30],
    'CITY': ['London', '', 'Austin'],
    'GENDER': ['F', 'M', 'M'],
    'ID': [15, 98, 12]
})

df2 = pd.DataFrame({
    'NAME': ['Kelly', 'Jack', 'Josh'],
    'AGE': [15, '', 30],
    'CITY': ['', 'Munich', 'Austin'],
    'GENDER': ['F', 'M', 'M'],
    'ID': [15, 98, 12]
})

# 将DataFrame转换为以ID为键的行字典
df1_row_dict = df1.set_index('ID').to_dict('index')
df2_row_dict = df2.set_index('ID').to_dict('index')

result_ids = []

# 遍历所有共同ID
for id_val in df1_row_dict.keys() & df2_row_dict.keys():
    row1 = df1_row_dict[id_val]
    row2 = df2_row_dict[id_val]
    is_match = True
    
    # 逐字段校验匹配规则
    for col in row1.keys():
        val1 = row1[col]
        val2 = row2[col]
        # 不满足规则的情况:值不等,且不是df2空、df1非空的场景
        if not (val1 == val2 or (val2 == '' and val1 != '')):
            is_match = False
            break
    
    if is_match:
        result_ids.append(id_val)

print(result_ids)  # 输出:[15, 12]

逻辑说明

  1. 先将两个DataFrame转为以ID为索引的字典,通过ID快速定位对应行
  2. 遍历每个共同ID,逐字段检查:
    • 要么字段值完全相等
    • 要么df2的字段值为空字符串,且df1的对应字段值非空
  3. 所有字段都满足规则时,将ID加入结果列表

方案二:Pandas矢量化操作(大数据量高效)

利用Pandas的批量运算能力,避免循环,适合处理大规模数据:

import pandas as pd

# 构造测试数据(同方案一)
df1 = pd.DataFrame({
    'NAME': ['Kelly', 'Jack', 'Josh'],
    'AGE': [15, 12, 30],
    'CITY': ['London', '', 'Austin'],
    'GENDER': ['F', 'M', 'M'],
    'ID': [15, 98, 12]
})

df2 = pd.DataFrame({
    'NAME': ['Kelly', 'Jack', 'Josh'],
    'AGE': [15, '', 30],
    'CITY': ['', 'Munich', 'Austin'],
    'GENDER': ['F', 'M', 'M'],
    'ID': [15, 98, 12]
})

# 按ID内连接两个DataFrame,对齐行数据
merged_df = pd.merge(df1, df2, on='ID', suffixes=('_df1', '_df2'))

# 获取需要对比的字段(排除ID)
compare_fields = [col.replace('_df1', '') for col in merged_df.columns if '_df1' in col]

# 生成每个字段的匹配条件
match_conditions = []
for field in compare_fields:
    col_df1 = f"{field}_df1"
    col_df2 = f"{field}_df2"
    # 条件:值相等 或 df2字段为空且df1字段非空
    condition = (merged_df[col_df1] == merged_df[col_df2]) | (merged_df[col_df2] == '' & merged_df[col_df1] != '')
    match_conditions.append(condition)

# 筛选出所有字段都满足条件的行
valid_rows = pd.concat(match_conditions, axis=1).all(axis=1)

# 提取符合条件的ID
result_ids = merged_df.loc[valid_rows, 'ID'].tolist()

print(result_ids)  # 输出:[15, 12]

逻辑说明

  1. 使用merge按ID对齐两个DataFrame,通过后缀区分来自不同DF的字段
  2. 对每一组对应字段生成匹配规则的布尔数组
  3. 用all(axis=1)检查每行是否所有字段都满足规则,最终提取符合条件的ID

结果解释

测试用例中ID98被排除的原因:df2的CITY字段为Munich(非空),而df1的CITY字段为空字符串,属于「df2非空但df1为空」的不匹配场景,不符合规则,因此不加入结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 17:55:02