如何在Pandas中高效遍历行(不使用iterrows())
解决Pandas大型DataFrame逐行遍历慢的问题
针对大型DataFrame用iterrows()速度慢的问题,给你几个实用的替代方案,优先级从高到低:
1. 优先用向量化操作(最快)
Pandas的核心优势是向量化计算,完全不用遍历,速度比任何循环都快。比如你给出的示例逻辑,直接用布尔索引就能实现:
# 提取income>50000的name列表 names = df.loc[df['income'] > 50000, 'name'].tolist()
如果是更复杂的多字段处理逻辑(比如根据A列值处理B列),同样可以用向量化方式实现:
import numpy as np # 根据A列值处理B列:A为'high'则乘2,否则除以2 df['processed_B'] = np.where(df['A'] == 'high', df['B'] * 2, df['B'] / 2) # 提取符合条件的name names = df.loc[df['income'] > 50000, 'name'].tolist()
2. 用itertuples替代iterrows(速度提升明显)
如果逻辑复杂到无法用向量化实现,优先用itertuples()——它返回命名元组(namedtuple),访问字段的开销远小于iterrows()返回的Series,速度能快好几倍。
对应你的示例逻辑:
names = [] for row in df.itertuples(index=False): # index=False不返回行索引,进一步提速 if row.income > 50000: names.append(row.name)
处理多字段+条件逻辑的例子:
names = [] processed_B = [] for row in df.itertuples(index=False): # 提取符合条件的name if row.income > 50000: names.append(row.name) # 根据A列处理B列 processed_B.append(row.B * 2 if row.A == 'high' else row.B / 2)
3. 用apply方法(代码简洁,速度优于iterrows)
如果逻辑相对简单,想保持代码简洁,可以用apply(),虽然速度不如向量化和itertuples,但比iterrows快很多。
示例:
import pandas as pd def process_single_row(row): # 封装逐行处理逻辑 target_name = row['name'] if row['income'] > 50000 else None processed_b = row['B'] * 2 if row['A'] == 'high' else row['B'] / 2 return pd.Series([target_name, processed_b], index=['target_name', 'processed_B']) # 按行应用处理函数 result_df = df.apply(process_single_row, axis=1) # 提取有效name列表 names = result_df['target_name'].dropna().tolist() # 提取处理后的B列数据 processed_B = result_df['processed_B'].tolist()
优先级总结
- 第一选择:向量化操作(速度最快,Pandas原生优化)
- 第二选择:itertuples(循环场景下速度最优)
- 第三选择:apply(代码简洁,适合简单逻辑)
- 最后选择:iterrows(仅当以上方法都无法实现时再用)
内容的提问来源于stack exchange,提问作者SBen
相关产品推荐
相关产品推荐

