替代df.iterrows:高效删除DataFrame同组内反向重复行
高效删除同组内反向元组对应的行
原始DataFrame结构
以下是创建目标DataFrame的代码:
import pandas as pd colA = ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c'] colB = [(21,1,2), (0,1,21), (2,1,21), (1,12,5), (21,1,0), (12,5,6), (18,7,14), (7,5,12), (14,7,18), (12,7,11), (11,7,12), (3,5,7)] df = pd.DataFrame(list(zip(colA, colB)), columns = ['colA', 'colB']) display(df)
执行后输出的原始数据:
colA colB 0 a (21, 1, 2) 1 a (0, 1, 21) 2 a (2, 1, 21) 3 a (1, 12, 5) 4 b (21, 1, 0) 5 b (12, 5, 6) 6 b (18, 7, 14) 7 b (7, 5, 12) 8 c (14, 7, 18) 9 c (12, 7, 11) 10 c (11, 7, 12) 11 c (3, 5, 7)
需求说明
需要删除同一colA分组内,colB值为另一行colB值反向元组的行:
- colA='a'分组中,第2行(2,1,21)是第0行(21,1,2)的反向,需删除第2行;
- 跨组反向无需处理:比如colA='b'的(21,1,0)是colA='a'中(0,1,21)的反向,不做删除;
- colA='c'分组中,第10行(11,7,12)是第9行(12,7,11)的反向,需删除第10行。
期望最终结果
colA colB 0 a (21, 1, 2) 1 a (0, 1, 21) 2 a (1, 12, 5) 3 b (21, 1, 0) 4 b (12, 5, 6) 5 b (18, 7, 14) 6 b (7, 5, 12) 7 c (14, 7, 18) 8 c (12, 7, 11) 9 c (3, 5, 7)
注意事项
- 操作建议在原始DataFrame的副本上进行,避免修改原始数据;
- 实际数据规模为300万行,需使用高效方案,
iterrows循环效率极低,不可用。
现有低效实现(iterrows版本)
以下是效率极低的逐行循环实现,不适用于大数据量:
unique_df = df.copy() seen_a_b = set() for i, row in df.iterrows(): val_a = row['colA'] val_b = row['colB'] a_b = (val_a, val_b) a_revb = (val_a, val_b[::-1]) if a_b in seen_a_b: unique_df.drop(i, inplace=True) continue seen_a_b.add(a_b) seen_a_b.add(a_revb)
高效解决方案
利用元组的可比较性,为每个colB生成标准化键(取元组和其反向元组中较小的一个),然后通过drop_duplicates保留每个(colA, 标准化键)组合的首次出现行,全程为向量化操作,处理300万行效率极高:
import pandas as pd # 复制原始数据,避免修改原数据 df_copy = df.copy() # 生成标准化键:对于每个元组,取其与反向元组中较小的那个作为唯一标识 df_copy['standard_key'] = df_copy['colB'].apply(lambda t: t if t < t[::-1] else t[::-1]) # 保留每个(colA, standard_key)组合的第一行,删除重复项 df_result = df_copy.drop_duplicates(subset=['colA', 'standard_key'], keep='first').drop(columns='standard_key') # 重置索引(可选) df_result = df_result.reset_index(drop=True) display(df_result)
方案说明
- 标准化键:反向的两个元组会生成相同的标准化键,比如(21,1,2)和(2,1,21)的标准化键都是(2,1,21)(因为(2,1,21) < (21,1,2));
- 去重逻辑:按
colA和standard_key组合去重,保留首次出现的行,自动删除同组内的反向元组行; - 性能优势:
apply针对Series批量处理,drop_duplicates是pandas底层优化的向量化操作,远快于逐行循环。
内容的提问来源于stack exchange,提问作者Lowrenzo
相关产品推荐
相关产品推荐

