pandas按指定容差查找重复行并为重复组分配集合编号的实现
pandas按指定容差分组并分配集合编号实现方案
实现思路
针对多列不同容差的重复行匹配需求,可通过DBSCAN密度聚类实现高效分组:
- 先将每个数值列按对应容差做归一化处理,此时两个样本的归一化后欧氏距离≤1,就代表所有列的差值都在容差允许范围内
- 调用DBSCAN聚类,设置邻域半径
eps=1、最小样本数min_samples=1,得到的簇编号就是分组依据,将编号+1即可得到从1开始的Set列
完整实现代码
首先导入依赖库:
import pandas as pd from sklearn.cluster import DBSCAN
构造输入数据和容差表:
# 构造输入数据 df = pd.DataFrame({ 'Name': ['aa', 'bb', 'cc', 'dd', 'aa', 'bb', 'cc', 'dd'], 'A': [0.002667, 0.0034, 0.0036, 0.003667, 0.003667, 0.0076, 0.007, 0.007], 'B': [2.5, 2.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], 'C': [13.5, 13.7, 13.6, 13.6, 13.6, 13.6, 13.6, 13.6] }) # 构造容差表 tolerance = pd.DataFrame({ 'A': [0.003], 'B': [0.2], 'C': [0.2] })
核心分组逻辑:
# 提取需要做容差匹配的列 match_cols = ['A', 'B', 'C'] # 按容差归一化数据 norm_data = df[match_cols] / tolerance.loc[0, match_cols] # 初始化DBSCAN:eps=1表示归一化后距离≤1的样本属于同一簇,min_samples=1表示单个样本也可成簇 dbscan = DBSCAN(eps=1, min_samples=1) # 训练得到簇编号,+1转换为从1开始的Set编号 df['Set'] = dbscan.fit_predict(norm_data) + 1
输出结果与预期完全一致:
print(df)
Name A B C Set 0 aa 0.002667 2.5 13.5 1 1 bb 0.003400 2.5 13.7 1 2 cc 0.003600 1.0 13.6 2 3 dd 0.003667 1.0 13.6 2 4 aa 0.003667 1.0 13.6 2 5 bb 0.007600 1.0 13.6 3 6 cc 0.007000 1.0 13.6 3 7 dd 0.007000 1.0 13.6 3
备选方案(无外部依赖)
如果数据量很小且不想引入sklearn依赖,也可以手动实现遍历分组逻辑:初始化Set列为0,按行遍历,将当前行和已分配分组的所有样本比较,若找到满足容差的组则归入该组,否则新建组。该方案时间复杂度为O(n²),仅适合小数据集使用。
内容的提问来源于stack exchange,提问作者Jagadeeshkumar Viswanathan
相关产品推荐
相关产品推荐

