如何用.apply()替代.iterrows()加速Pandas DataFrame行处理?
解决方法
最优选择:向量化操作(比apply/iterrows快得多)
Pandas的核心优势就是向量化运算,完全不用逐行循环,直接对整个数据集批量处理,效率拉满:
# 先把所有ID列挑出来(排除mean列) id_columns = [col for col in df.columns if col.startswith('ID_')] # 生成布尔矩阵,标记每行里ID列数值大于该行mean的位置 mask = df[id_columns] > df['mean'].values[:, None] # 把mean列广播成和ID列同维度的矩阵 # 计算每行符合条件的数值之和,存入新列 df['sum_above_mean'] = df[id_columns].where(mask, 0).sum(axis=1) # 如果需要记录对应的ID(列名里_后面的部分),可以加这列 df['above_mean_ids'] = mask.apply( lambda row: [col.split('_')[1] for col, is_above in zip(id_columns, row) if is_above], axis=1 )
用apply实现(比iterrows快,但不如向量化)
如果一定要用apply,得把你的代码逻辑彻底修正:
def process_row(row): row_mean = row['mean'] # 筛选ID列中数值大于均值的部分 filtered_vals = row.filter(like='ID_')[row.filter(like='ID_') > row_mean] # 求和 total = filtered_vals.sum() # 提取对应的ID ids = [col.split('_')[1] for col in filtered_vals.index] # 返回结果,让apply可以展开成多列 return total, ids # 把结果拆成两列存入DataFrame df[['sum_above_mean', 'above_mean_ids']] = df.apply(process_row, axis=1, result_type='expand')
你的原代码问题在哪?
- 逻辑混乱:你用
x.index取的是所有列名,不是目标ID;用x[x.name]完全是错误的取值方式,根本没筛选ID列 - 没有返回值:apply需要函数返回结果才能赋值到新列,你的函数没return任何内容
- 求和错误:
sum(x)是对整行所有元素求和,不是筛选后的符合条件的数值
效率对比
- 向量化:最快,底层用C实现,大数据量下比Python循环快几十甚至上百倍
- apply:比iterrows快,但本质还是逐行跑Python函数,数据量大时依然慢
- iterrows:最慢,每次循环都要把行转成Series,开销极大
内容的提问来源于stack exchange,提问作者SnowGepard
相关产品推荐
相关产品推荐

