我想对数据框架中的财务数据按顺序执行自己的复杂操作。

例如,我正在使用以下来自雅虎财经的MSFT CSV文件:

Date,Open,High,Low,Close,Volume,Adj Close
2011-10-19,27.37,27.47,27.01,27.13,42880000,27.13
2011-10-18,26.94,27.40,26.80,27.31,52487900,27.31
2011-10-17,27.11,27.42,26.85,26.98,39433400,26.98
2011-10-14,27.31,27.50,27.02,27.27,50947700,27.27

....

然后我做以下事情:

#!/usr/bin/env python
from pandas import *

df = read_csv('table.csv')

for i, row in enumerate(df.values):
    date = df.index[i]
    open, high, low, close, adjclose = row
    #now perform analysis on open/close based on date, etc..

这是最有效的方法吗?考虑到在pandas中对速度的关注,我认为必须有一些特殊的函数以一种也检索索引的方式遍历值(可能通过生成器来提高内存效率)?df。不幸的是Iteritems只逐列迭代。


当前回答

当然,遍历数据帧的最快方法是通过df访问底层numpy ndarray。值(如您所做的那样)或通过分别访问每一列df.column_name.values。因为你也想访问索引,你可以使用df.index.values。

index = df.index.values
column_of_interest1 = df.column_name1.values
...
column_of_interestk = df.column_namek.values

for i in range(df.shape[0]):
   index_value = index[i]
   ...
   column_value_k = column_of_interest_k[i]

不是神谕的吗?当然。但很快。

如果你想从循环中挤出更多的果汁,你会想看看cython。Cython将让你获得巨大的加速(想想10 -100倍)。检查cython的内存视图以获得最大性能。

其他回答

正如@joris指出的那样,iterrows比itertuples慢得多,itertuples比iterrows快大约100倍,我在一个有500万条记录的DataFrame中测试了这两种方法的速度,结果是iterrows的速度为1200it/s,而itertuples的速度为120000it/s。

如果使用itertuple,请注意for循环中的每个元素都是namedtuple,因此要获得每个列中的值,可以参考下面的示例代码

>>> df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]},
                      index=['a', 'b'])
>>> df
   col1  col2
a     1   0.1
b     2   0.2
>>> for row in df.itertuples():
...     print(row.col1, row.col2)
...
1, 0.1
2, 0.2

在注意到Nick Crawford的答案后,我检查了iterrows,但发现它产生(index, Series)元组。不确定哪种方法最适合您,但我最终使用了itertuples方法来解决我的问题,该方法生成(index, row_value1…)元组。

还有iterkv,它遍历(column, series)元组。

最新版本的pandas现在包含了一个用于遍历行的内置函数。

for index, row in df.iterrows():

    # do some logic here

或者,如果你想要更快,可以使用itertuples()

但是,unutbu建议使用numpy函数来避免遍历行,这会产生最快的代码。

另一个建议是将groupby与向量化计算结合起来,如果行的子集共享允许这样做的特征。

作为一个小的补充,如果你有一个复杂的函数,你可以应用到一个单列:

http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.apply.html

df[b] = df[a].apply(lambda col: do stuff with col here)