Pandas 行间多列一致性校验:识别重复键下的值冲突

本文介绍如何使用 pandas 对 dataframe 中具有相同“country”和“reference year”组合的行进行批量比对,自动标记存在不一致 value 值的记录为 "invalid",实现高效的数据质量校验。

在数据清洗与校验场景中,常需识别逻辑上应保持一致但实际取值冲突的记录——例如同一国家、同一年份下出现多个不同数值,即视为数据异常。直接使用 np.where 对整列做逐元素布尔比较(如原尝试 df1['value'] != df1['value'])不仅无法实现跨行聚合比对,还会因维度不匹配报错 "ValueError: Expected a 1D array..."。

正确解法是基于分组聚合思想:以 ['Country', 'Reference Year'] 为复合键分组,统计每组内 value 的唯一值个数(nunique)。若某组 nunique > 1,说明该组存在至少两个不同 value(含空字符串 '' 与 '32' 这类显式差异),则整组标记为 "Invalid";否则为 "Valid"。

核心代码如下:

import pandas as pd
import numpy as np

df1 = pd.DataFrame(
    data=[['Afghanistan','2015','5.1'],
          ['Afghanistan','2015','6.1'],
          ['Bahrain','2025',''],
          ['Bahrain','2025','32'],
          ['Bahrain','2025','32'],
          ['Bahrain','2025','32']],
    columns=['Country', 'Reference Year', 'value']
)

df1['Validity'] = np.where(
    df1.groupby(['Country', 'Reference Year'])['value'].transform('nunique').gt(1),
    'Invalid',
    'Valid'
)

执行后得到结果:

Country Reference Year value Validity
Afghanistan 2015 5.1 Invalid
Afghanistan 2015 6.1 Invalid
Bahrain 20

25
Invalid
Bahrain 2025 32 Invalid
Bahrain 2025 32 Valid
Bahrain 2025 32 Valid

关键说明

  • groupby(...).transform('nunique') 保证输出与原始 DataFrame 等长,且每行填入其所属组的 value 唯一值数量;
  • .gt(1) 是 > 1 的向量化写法,返回布尔 Series;
  • 空字符串 '' 与 '32' 被视为不同值,因此 ['', '32'] 的 nunique 为 2,触发 "Invalid";
  • 若需将空值('' 或 NaN)统一视作缺失并忽略参与比较,可在 groupby 前先做清洗,例如:
    df1['value_clean'] = df1['value'].replace('', np.nan)
    # 然后对 value_clean 执行 transform('nunique')

该方法简洁、向量化、可扩展,适用于任意多列组合键的重复值一致性校验,是 Pandas 数据质量管控的标准实践之一。