我有一个熊猫数据帧,df:
c1 c2
0 10 100
1 11 110
2 12 120
如何迭代此数据帧的行?对于每一行,我希望能够通过列的名称访问其元素(单元格中的值)。例如:
for row in df.rows:
print(row['c1'], row['c2'])
我发现了一个类似的问题,建议使用以下任一项:
for date, row in df.T.iteritems():
for row in df.iterrows():
但我不知道row对象是什么,以及如何使用它。
虽然iterrows()是一个很好的选项,但有时itertples()会快得多:
df = pd.DataFrame({'a': randn(1000), 'b': randn(1000),'N': randint(100, 1000, (1000)), 'x': 'x'})
%timeit [row.a * 2 for idx, row in df.iterrows()]
# => 10 loops, best of 3: 50.3 ms per loop
%timeit [row[1] * 2 for row in df.itertuples()]
# => 1000 loops, best of 3: 541 µs per loop
在Pandas数据帧中有很多方法可以迭代行。一种非常简单直观的方法是:
df = pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6], 'C':[7, 8, 9]})
print(df)
for i in range(df.shape[0]):
# For printing the second column
print(df.iloc[i, 1])
# For printing more than one columns
print(df.iloc[i, [0, 2]])
免责声明:尽管这里有很多答案建议不要使用迭代(循环)方法(我基本同意),但我仍然认为这是一种适用于以下情况的合理方法:
使用API中的数据扩展数据帧
假设您有一个包含不完整用户数据的大型数据帧。现在,您必须使用其他列来扩展此数据,例如,用户的年龄和性别。
这两个值都必须从后端API获取。我假设API不提供“批处理”端点(一次接受多个用户ID)。否则,您应该只调用一次API。
网络请求的成本(等待时间)远远超过了数据帧的迭代。我们讨论的是数百毫秒的网络往返时间,相比之下,使用迭代的替代方法可以忽略不计的小增益。
每行一个昂贵的网络请求
所以在这种情况下,我绝对倾向于使用迭代方法。尽管网络请求很昂贵,但可以保证对数据帧中的每一行只触发一次。以下是使用DataFrame.iterrows的示例:
实例
for index, row in users_df.iterrows():
user_id = row['user_id']
# Trigger expensive network request once for each row
response_dict = backend_api.get(f'/api/user-data/{user_id}')
# Extend dataframe with multiple data from response
users_df.at[index, 'age'] = response_dict.get('age')
users_df.at[index, 'gender'] = response_dict.get('gender')
DataFrame.iterrows是一个生成索引和行(作为一个系列)的生成器:
import pandas as pd
df = pd.DataFrame({'c1': [10, 11, 12], 'c2': [100, 110, 120]})
df = df.reset_index() # make sure indexes pair with number of rows
for index, row in df.iterrows():
print(row['c1'], row['c2'])
10 100
11 110
12 120