
本文介绍如何使用 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','2020',''],
['Bahrain','2020','32'],
['Bahrain','2021','32'],
['Bahrain','2022','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 | 2020 | Invalid | |
| Bahrain | 2020 | 32 | Invalid |
| Bahrain | 2021 | 32 | Valid |
| Bahrain | 2022 | 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 数据质量管控的标准实践之一。










