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

Pandas iterrows运行过慢,60万行数据缺失值填充的更快替代方案

针对60万行数据集的缺失值填充优化方案

原代码使用iterrows()逐行迭代,再嵌套列循环+at赋值,这种Python层面的循环在大数据量下效率极低,核心优化思路是用pandas的向量化操作替代逐行迭代,以下是两种高效替代方案:

方案一:预计算分组中位数映射(适配自定义get_median逻辑)

如果get_median是调用外部接口或基于外部数据计算中位数,优先用这种方式,避免循环中重复调用:

%%time
import numpy as np
import pandas as pd

df_inputed = df.copy()

# 1. 预计算所有唯一分组的中位数,构建映射字典
unique_groups = df_to_inpute[['sic', 'year', 'quarter']].drop_duplicates()
group_median_map = {}
for _, row in unique_groups.iterrows():
    sic, year, quarter = row['sic'], row['year'], row['quarter']
    median_val = get_median(sic, year, quarter)
    if not np.isnan(median_val):
        group_median_map[(sic, year, quarter)] = median_val

# 2. 生成分组键列,用于匹配中位数
df_to_inpute['_group_key'] = df_to_inpute.apply(lambda x: (x['sic'], x['year'], x['quarter']), axis=1)

# 3. 批量填充每个目标列的缺失值
for col in cols_to_check:
    # 获取每行对应的中位数(无匹配则为NaN)
    median_series = df_to_inpute['_group_key'].map(group_median_map)
    # 仅填充原列是NaN且中位数存在的行
    df_inputed[col] = df_inputed[col].fillna(median_series)

# 清理临时列
df_to_inpute.drop('_group_key', axis=1, inplace=True)

方案二:直接用groupby.transform(适配中位数基于当前数据集的场景)

如果get_median的逻辑就是计算当前数据集中对应分组的中位数,可直接用pandas内置的分组操作,代码更简洁高效:

%%time
import pandas as pd

df_inputed = df.copy()

for col in cols_to_check:
    # 按sic/year/quarter分组计算中位数,自动匹配到每行并填充缺失值
    df_inputed[col] = df_inputed[col].fillna(
        df_inputed.groupby(['sic', 'year', 'quarter'])[col].transform('median')
    )

为什么这些方案更快?

  • 向量化操作是pandas底层用C实现的,避免了Python循环的解释器开销,处理60万行数据的速度会比原代码快100~1000倍
  • 预计算分组中位数避免了重复调用get_median,减少了冗余计算/IO
  • groupby.transform直接将分组计算结果广播到原数据集的每行,无需手动索引匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 22:30:11