这是一个在数据分析中非常常用,但也需要谨慎使用的方法。

核心概念
.iterrows() 是 Pandas DataFrame 对象的一个方法,它的作用是逐行迭代一个 DataFrame,对于每一行,它会返回两个值:
- 行的索引 (index)
- 包含该行所有数据的 Pandas Series (a Pandas Series representing the data)
基本语法和用法
import pandas as pd
# 1. 创建一个示例 DataFrame
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David'],
'Age': [25, 30, 35, 28],
'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)
print("原始 DataFrame:")
print(df)
print("-" * 30)
# 2. 使用 iterrows() 进行迭代
print("使用 iterrows() 遍历 DataFrame:")
for index, row in df.iterrows():
# index 是当前行的索引 (0, 1, 2, ...)
# row 是一个 Pandas Series,包含了该行的所有数据
print(f"行索引: {index}")
print(f"行数据 (Series):\n{row}")
print(f"访问特定列: 姓名={row['Name']}, 年龄={row['Age']}")
print("-" * 20)
输出结果:
原始 DataFrame:
Name Age City
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago
3 David 28 Houston
------------------------------
使用 iterrows() 遍历 DataFrame:
行索引: 0
行数据 (Series):
Name Alice
Age 25
City New York
Name: 0, dtype: object
访问特定列: 姓名=Alice, 年龄=25
--------------------
行索引: 1
行数据 (Series):
Name Bob
Age 30
City Los Angeles
Name: 1, dtype: object
访问特定列: 姓名=Bob, 年龄=30
--------------------
行索引: 2
行数据 (Series):
Name Charlie
Age 35
City Chicago
Name: 2, dtype: object
访问特定列: 姓名=Charlie, 年龄=35
--------------------
行索引: 3
行数据 (Series):
Name David
Age 28
City Houston
Name: 3, dtype: object
访问特定列: 姓名=David, 年龄=28
--------------------
关键特点与重要注意事项
性能问题(最重要的注意事项)
.iterrows() 的性能非常差。在绝大多数情况下,它都不是遍历 DataFrame 的最佳方式。
- 原因:
.iterrows()为 DataFrame 的每一行都创建了一个新的 Pandas Series 对象,这个创建和销毁对象的过程会带来巨大的开销,尤其是在处理大型 DataFrame 时,会变得非常慢。 - 替代方案:对于简单的逐行操作,或者需要修改 DataFrame 的值,强烈推荐使用
.itertuples(),它的速度要快得多(通常快几个数量级)。
数据类型问题
从 .iterrows() 返回的 row 是一个 Pandas Series,这意味着:

- 列名成为 Series 的索引:你可以通过
row['列名']或row.列名来访问数据。 - 数据类型会保留:Series 中的数据会保持其在 DataFrame 中原有的数据类型(如
int,str,float等)。
这与 .itertuples() 返回一个命名元组不同,后者通常访问起来更快且更直观。
.iterrows() vs. .itertuples() (性能对比)
让我们通过一个简单的性能测试来直观感受它们的差异。
import pandas as pd
import time
# 创建一个更大的 DataFrame
df_large = pd.DataFrame({'A': range(100000), 'B': range(100000, 200000)})
# --- 测试 iterrows() ---
start_time = time.time()
for index, row in df_large.iterrows():
# 做一些简单的操作
_ = row['A'] + row['B']
iterrows_time = time.time() - start_time
print(f"iterrows() 耗时: {iterrows_time:.4f} 秒")
# --- 测试 itertuples() ---
start_time = time.time()
for row_tuple in df_large.itertuples():
# 访问元组元素,速度更快
_ = row_tuple.A + row_tuple.B
itertuples_time = time.time() - start_time
print(f"itertuples() 耗时: {itertuples_time:.4f} 秒")
# --- 测试向量化操作 (最佳实践) ---
start_time = time.time()
# 这是 Pandas 推荐的最高效的方式
_ = df_large['A'] + df_large['B']
vectorized_time = time.time() - start_time
print(f"向量化操作 耗时: {vectorized_time:.4f} 秒")
在我的机器上可能的输出:
iterrows() 耗时: 5.2341 秒
itertuples() 耗时: 0.0152 秒
向量化操作 耗时: 0.0010 秒
结论显而易见:

- 向量化操作 >
.itertuples()>>.iterrows()
何时应该使用 .iterrows()?
尽管有性能问题,但在某些特定场景下,.iterrows() 仍然有其用武之地:
-
需要访问行索引和行数据:当你迭代时,同时需要知道当前行的索引(
index)和该行的完整数据(rowSeries)时,.iterrows()非常方便。.itertuples()也可以通过row_tuple.Index获取索引,但不如.iterrows()直接。 -
逐行修改 DataFrame(不推荐,但可行): 你可以在循环中修改 Series 的值,然后将其赋回给 DataFrame。这通常也很慢,并且可能会引发
SettingWithCopyWarning警告。for index, row in df.iterrows(): if row['Age'] > 30: # 修改 'Age' 列的值 df.at[index, 'Age'] = row['Age'] + 1 print("\n修改后的 DataFrame:") print(df)输出:
修改后的 DataFrame: Name Age City 0 Alice 25 New York 1 Bob 30 Los Angeles 2 Charlie 36 Chicago 3 David 28 Houston更好的做法:使用布尔索引进行向量化修改。
# 更高效的方式 df.loc[df['Age'] > 30, 'Age'] += 1
-
复杂的、逐行的逻辑:当你的操作逻辑非常复杂,无法用向量化操作(如
apply或布尔索引)表示,且必须逐行处理时,.iterrows()是一个可用的(尽管不是最高效的)选择。
总结与最佳实践
| 特性 | .iterrows() |
.itertuples() |
向量化操作 |
|---|---|---|---|
| 速度 | 慢 | 快 | 最快 |
| 返回值 | (index, Series) |
namedtuple |
Series 或 DataFrame |
| 访问数据 | row['col'] 或 row.col |
row.col (更直观) |
df['col'] |
| 主要用途 | 需要索引和行数据 | 快速逐行迭代 | 首选,对列进行数学/逻辑运算 |
| Pandas哲学 | 避免,仅在必要时使用 | 推荐的迭代方式 | 最高效的Pandas方式 |
黄金法则:
- 永远优先尝试使用向量化操作,这是 Pandas 的核心优势,也是性能最优的解决方案。
df['A'] * df['B'],df[df['A'] > 10]。 - 如果必须逐行迭代,优先使用
.itertuples(),它在绝大多数情况下都比.iterrows()快得多,且足够方便。 - 只在极少数情况下才考虑使用
.iterrows(),例如你确实需要同时获取行索引和行 Series,并且性能不是瓶颈。
Pandas 的设计初衷就是为了避免像 Python 原生列表那样的逐行循环,而是利用底层的 NumPy 实现高效的向量化计算。
