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

百万行43列DataFrame:替代iterrows()的反向行对高效删除方案

问题

处理100万行、43列的DataFrame时,现有代码运行极慢。需求是:找出特定列值相同且CA列值互为相反数的行对,删除这类反向行对。

示例说明

假设有DataFrame df:

Column AColumn BColumn CColumn D
'Brown''Bottle'1234555100
'yellow''Cup'123455580
'Red''Bottle'1234555-100
'Red''Bottle'1234555-100
'Brown''Bottle'1234533100

若指定列B和列C进行匹配,需删除第1行和第3行(二者列B、列C值相同,列D值互为相反数),最终输出:

Column AColumn BColumn CColumn D
'yellow''Cup'123455580
'Red''Bottle'1234555-100
'Brown''Bottle'1234533100

低效代码(使用iterrows())

df_dupes = data[data.duplicated(subset = criteria_, keep=False)]
df_dupes_list = np.array(df_dupes.to_numpy().tolist())

df_1 = df_dupes_list[:,[0,1,7,9,8,23,35]]

df_2 = df_1.tolist()

for i, row in df_dupes.iterrows():
    if row.ConvertedAUD < 0 and [row.BA, row.OA, row.BN, row.DN, row.DT,row.D, -row.CA] in df_2:
        try:
            c = np.where((data['BA'] ==row.BA) & (data['OA'] ==row.OA) & (data['BN'] ==row.BN)& (data['DT'] ==row.DT)& (data['DN'] ==row.DN)& (data['D'] ==row.D)& (data['CA'] ==-row.CA))[0][0]

            data.drop(labels=[i,data.index.values[c]], axis=0, inplace=True)
        except:
            pass

高效解决方案

核心思路是用Pandas向量化操作替代逐行循环,避免iterrows()的低效问题,具体步骤如下:

1. 标记匹配组

按指定匹配列(对应代码中的BA, OA, BN, DN, DT, D)分组,同时为每行记录CA列的绝对值,方便后续查找相反数对。

2. 统计每组内正负值数量

对每个匹配组,分别统计CA为正、为负的行数,确定可抵消删除的行对数量。

3. 生成待删除行索引

  • 对有可删除对的组,取出CA为正和为负的行索引
  • 按两组中更少的行数选取对应数量的行对,标记为待删除项
  • 去重避免重复删除同一行

代码实现

import pandas as pd

# 定义匹配列和目标CA列
match_cols = ['BA', 'OA', 'BN', 'DN', 'DT', 'D']
ca_col = 'CA'

# 1. 生成匹配键+CA绝对值的组合,保留原始索引
data['abs_ca'] = data[ca_col].abs()
group_key = match_cols + ['abs_ca']

# 2. 分组统计正负CA的数量
group_stats = data.groupby(group_key).agg(
    pos_count=pd.NamedAgg(column=ca_col, aggfunc=lambda x: (x > 0).sum()),
    neg_count=pd.NamedAgg(column=ca_col, aggfunc=lambda x: (x < 0).sum())
).reset_index()

# 3. 计算每组可删除的行对数量
group_stats['delete_pairs'] = group_stats[['pos_count', 'neg_count']].min(axis=1)

# 4. 筛选出有可删除对的组
valid_groups = group_stats[group_stats['delete_pairs'] > 0]

# 5. 收集待删除的索引
to_delete = []
for _, row in valid_groups.iterrows():
    # 构建当前组的筛选条件
    mask = (data[match_cols] == row[match_cols]).all(axis=1) & (data['abs_ca'] == row['abs_ca'])
    group_data = data[mask]
    
    # 取出对应数量的正、负CA行索引
    pos_indices = group_data[group_data[ca_col] > 0].index[:row['delete_pairs']]
    neg_indices = group_data[group_data[ca_col] < 0].index[:row['delete_pairs']]
    
    to_delete.extend(pos_indices)
    to_delete.extend(neg_indices)

# 6. 去重后删除行,清理临时列
to_delete = list(set(to_delete))
data_cleaned = data.drop(to_delete).drop(columns=['abs_ca'])

效率提升原因

  • 全程使用Pandas向量化分组、聚合操作,比逐行迭代快数倍甚至数十倍
  • 仅在处理分组统计结果时用了一次循环,循环次数远小于原始数据行数
  • 避免了原代码中np.where全局查找、列表in判断这类高耗时操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:01:21