如何有效地迭代
如果你真的需要迭代Pandas数据框,你可能会想要避免使用iterrows()
。有不同的方法,通常的方法iterrows()
远非最佳选择。使用itertuples()
可快100倍。
简而言之:
- 一般情况下,请使用
df.itertuples(name=None)
。特别是当您有固定数量的列且少于255列时。 见第(3)点
- 否则,请使用
df.itertuples()
,除非您的列具有特殊字符,例如空格或'-'。 见第(2)点
- 即使您的数据框具有奇怪的列名,也可以使用最后一个示例中的
itertuples()
。 见第(4)点
- 只有在无法使用前面的解决方案时才使用
iterrows()
。 见第(1)点
在Pandas数据框中迭代行的不同方法:
生成一个有一百万行和四列的随机数据框:
df = pd.DataFrame(np.random.randint(0, 100, size=(1000000, 4)), columns=list('ABCD'))
print(df)
通常的iterrows()
很方便,但速度非常慢:
start_time = time.clock()
result = 0
for _, row in df.iterrows():
result += max(row['B'], row['C'])
total_elapsed_time = round(time.clock() - start_time, 2)
print("1. Iterrows done in {} seconds, result = {}".format(total_elapsed_time, result))
默认的itertuples()
已经非常快,但是如果你的列名重复或者一个列名不能简单地转换为Python变量名,那么它将无法使用。例如My Col-Name is very Strange
,应该避免使用此方法。
start_time = time.clock()
result = 0
for row in df.itertuples(index=False):
result += max(row.B, row.C)
total_elapsed_time = round(time.clock() - start_time, 2)
print("2. Named Itertuples done in {} seconds, result = {}".format(total_elapsed_time, result))
使用名为None的默认itertuples()
速度更快,但不太方便,因为您必须为每列定义一个变量。
start_time = time.clock()
result = 0
for(_, col1, col2, col3, col4) in df.itertuples(name=None):
result += max(col2, col3)
total_elapsed_time = round(time.clock() - start_time, 2)
print("3. Itertuples done in {} seconds, result = {}".format(total_elapsed_time, result))
最后,所命名的itertuples()
比前面的方法慢,但您不必为每个列定义一个变量,并且它可以使用诸如My Col-Name is very Strange
之类的列名。
start_time = time.clock()
result = 0
for row in df.itertuples(index=False):
result += max(row[df.columns.get_loc('B')], row[df.columns.get_loc('C')])
total_elapsed_time = round(time.clock() - start_time, 2)
print("4. Polyvalent Itertuples working even with special characters in the column name done in {} seconds, result = {}".format(total_elapsed_time, result))
输出:
A B C D
0 41 63 42 23
1 54 9 24 65
2 15 34 10 9
3 39 94 82 97
4 4 88 79 54
... .. .. .. ..
999995 48 27 4 25
999996 16 51 34 28
999997 1 39 61 14
999998 66 51 27 70
999999 51 53 47 99
[1000000 rows x 4 columns]
1. Iterrows done in 104.96 seconds, result = 66151519
2. Named Itertuples done in 1.26 seconds, result = 66151519
3. Itertuples done in 0.94 seconds, result = 66151519
4. Polyvalent Itertuples working even with special characters in the column name done in 2.94 seconds, result = 66151519
这篇文章是关于iterrows和itertuples之间非常有趣的比较
row
不是一个 Series,而应该是一个元组。但是如果你使用for idx, row in df.iterrows()
,row['A']
应该能正常工作。 - ayhan