我有一个熊猫数据帧,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对象是什么,以及如何使用它。
您还可以进行NumPy索引,以实现更高的速度。它不是真正的迭代,但对某些应用程序来说,它比迭代好得多。
subset = row['c1'][0:5]
all = row['c1'][:]
您可能还希望将其强制转换为数组。这些索引/选择本来应该像NumPy数组一样,但我遇到了一些问题,需要转换
np.asarray(all)
imgs[:] = cv2.resize(imgs[:], (224,224) ) # Resize every image in an hdf5 file
有时,有用的模式是:
# Borrowing @KutalmisB df example
df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])
# The to_dict call results in a list of dicts
# where each row_dict is a dictionary with k:v pairs of columns:value for that row
for row_dict in df.to_dict(orient='records'):
print(row_dict)
结果是:
{'col1':1.0, 'col2':0.1}
{'col1':2.0, 'col2':0.2}
正如公认的答案所述,在行上应用函数的最快方法是使用矢量化函数,即所谓的NumPy-ufuncs(通用函数)。
但是,当您要应用的函数尚未在NumPy中实现时,应该怎么做?
好吧,使用numba的矢量化装饰器,您可以轻松地直接在Python中创建ufunc,如下所示:
from numba import vectorize, float64
@vectorize([float64(float64)])
def f(x):
#x is your line, do something with it, and return a float
此函数的文档如下:创建NumPy通用函数
更新:cs95更新了他的答案,包括简单的numpy矢量化。你可以简单地参考他的答案。
cs95表明,Pandas矢量化在使用数据帧计算数据方面远远优于其他Pandas方法。
我想补充一点,如果您首先将数据帧转换为NumPy数组,然后使用矢量化,它甚至比Pandas数据帧矢量化更快(这包括将其转换回数据帧序列的时间)。
如果您将以下函数添加到cs95的基准代码中,这将变得非常明显:
def np_vectorization(df):
np_arr = df.to_numpy()
return pd.Series(np_arr[:,0] + np_arr[:,1], index=df.index)
def just_np_vectorization(df):
np_arr = df.to_numpy()
return np_arr[:,0] + np_arr[:,1]
为了循环数据帧中的所有行并方便地使用每行的值,可以将命名元组转换为ndarray。例如:
df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])
在行上循环:
for row in df.itertuples(index=False, name='Pandas'):
print np.asarray(row)
结果是:
[ 1. 0.1]
[ 2. 0.2]
请注意,如果index=True,则将索引添加为元组的第一个元素,这对于某些应用程序来说可能是不可取的。