如何检测混合类型变量的近似重复行(年龄允许±1误差)
解决方案:NAME&COUNTRY匹配+AGE±1近似重复检测
刚好遇到过类似的需求,我来给你两个实用的解决方案,既能覆盖整数年龄,也能轻松适配非整数类型的场景。
首先先还原你的数据集,方便后续测试:
import pandas as pd data = [ ['Fred', 23, 'America', 'Banker'], ['Paula', 78, 'Germany', 'Retired'], ['Fred', 23, 'America', 'Banker'], ['Fred', 22, 'America', 'Student'], ['Fred', 23, 'Brazil', 'Police Officer'], ['Bingo', 36, 'New Zealand', 'Money'] ] df = pd.DataFrame(data, columns=['NAME', 'AGE', 'COUNTRY', 'PROFESSION'])
方法一:分组后逐行匹配(直观易理解)
核心思路是先按NAME和COUNTRY分组,确保只在同姓名同国家的范围内找近似重复;然后在每组内,为每一行筛选出年龄差≤1的所有行,最后去重得到结果。
def find_approx_duplicates(group): matched_indices = [] # 遍历组内每一行,找符合年龄条件的行索引 for idx, row in group.iterrows(): # 用绝对值判断年龄差≤1,兼容整数和非整数 matches = group[abs(group['AGE'] - row['AGE']) <= 1].index matched_indices.extend(matches) # 去重后返回对应的行 return group.loc[pd.unique(matched_indices)] # 分组应用函数,得到近似重复行 approx_dup_df = df.groupby(['NAME', 'COUNTRY'], group_keys=False).apply(find_approx_duplicates)
运行后得到的结果就是你期望的:
NAME AGE COUNTRY PROFESSION 0 Fred 23 America Banker 2 Fred 23 America Banker 3 Fred 22 America Student
方法二:自连接筛选(大数据集更高效)
如果你的数据集很大,分组逐行遍历效率可能偏低,可以用自连接的方式,先扩展每行的年龄范围,再匹配符合条件的行:
# 临时添加年龄上下限列 df['AGE_low'] = df['AGE'] - 1 df['AGE_high'] = df['AGE'] + 1 # 自连接,匹配NAME、COUNTRY相同,且对方年龄在当前行的上下限内 merged = df.merge( df, on=['NAME', 'COUNTRY'], suffixes=('_orig', '_match') ).query('AGE_match >= AGE_low_orig and AGE_match <= AGE_high_orig') # 提取原数据中的唯一行(保留原索引去重) approx_dup_df = df.loc[pd.unique(merged['index_orig'])].reset_index(drop=True) # 清理临时列 df.drop(['AGE_low', 'AGE_high'], axis=1, inplace=True)
这个方法的结果和方法一完全一致,而且因为用了pandas的向量化操作,处理大数据集时速度更快。
适配非整数类型的小调整
如果你的AGE列是浮点数(比如22.5、23.2),只需要保留方法一中的绝对值差判断逻辑即可(上面的代码已经默认支持),比如:
matches = group[abs(group['AGE'] - row['AGE']) <= 1].index
这样不管是整数还是小数,只要年龄差在±1范围内,都会被正确匹配到。
内容的提问来源于stack exchange,提问作者Nnn
相关产品推荐
相关产品推荐

