You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

替代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)

方案说明

  1. 标准化键:反向的两个元组会生成相同的标准化键,比如(21,1,2)和(2,1,21)的标准化键都是(2,1,21)(因为(2,1,21) < (21,1,2));
  2. 去重逻辑:按colA和standard_key组合去重,保留首次出现的行,自动删除同组内的反向元组行;
  3. 性能优势:apply针对Series批量处理,drop_duplicates是pandas底层优化的向量化操作,远快于逐行循环。

内容的提问来源于stack exchange,提问作者Lowrenzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:05:20