我希望以顺序方式对数据框中的财务数据执行我自己的复杂操作 .
例如,我使用从Yahoo Finance获取的以下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..
这是最有效的方式吗?鉴于对大熊猫速度的关注,我认为必须有一些特殊的函数来迭代遍历值,同时也检索索引(可能通过生成器来节省内存)?遗憾的是, df.iteritems
只是逐列迭代 .
10 回答
Pandas基于NumPy阵列 . 使用NumPy阵列加速的关键是一次性对整个阵列执行操作,而不是逐行或逐项执行 .
例如,如果
close
是一维数组,并且您希望每日百分比更改,这会将整个百分比变化数组计算为一个语句,而不是
因此,尽量完全避免Python循环
for i, row in enumerate(...)
,并考虑如何在整个数组(或数据帧)上对整个操作执行计算,而不是逐行 .您可以通过转置然后调用iteritems来遍历行:
在这种情况下,我不确定效率 . 为了在迭代算法中获得最佳性能,您可能希望探索在Cython中编写它,因此您可以执行以下操作:
我建议首先在纯Python中编写算法,确保它的工作原理并查看速度有多快 - 如果速度不够快,将事物转换为Cython就像这样,只需要很少的工作就可以得到与手工编码C一样快的东西/C .
正如@joris指出的那样,
iterrows
比itertuples
慢得多itertuples
比iterrows
大约100倍,我测试了数据帧中两种方法的速度,5027505记录结果是iterrows
,它是1200it / s,itertuples
是120000it /秒 .如果使用
itertuples
,请注意for循环中的每个元素都是一个namedtuple,因此要获取每列中的值,可以参考以下示例代码当然,迭代数据帧的最快方法是通过
df.values
(正如你所做)或通过单独访问每一列df.column_name.values
来访问底层的numpy ndarray . 由于您也想要访问索引,因此可以使用df.index.values
.不是pythonic?当然 . 但很快 .
如果你想从循环中挤出更多的果汁,你会想要查看cython . Cython将让你获得巨大的加速(想想10x-100x) . 为了获得最佳性能,请检查memory views for cython .
与前面提到的一样,pandas对象在一次处理整个数组时效率最高 . 然而对于那些真正需要循环通过pandas DataFrame执行某些操作的人,比如我,我发现至少有三种方法可以做到这一点 . 我做了一个简短的测试,看看三者中哪一个耗时最少 .
结果:
这可能不是衡量时间消耗的最佳方法,但它对我来说很快 .
以下是一些利弊恕我直言:
.iterrows():在单独的变量中返回索引和行项,但速度明显较慢
.itertuples():比.iterrows()快,但返回索引和行项,ir [0]是索引
zip:最快,但无法访问该行的索引
最新版本的pandas现在包含一个用于迭代行的内置函数 .
或者,如果你想要更快使用
itertuples()
但是,unutbu建议使用numpy函数来避免遍历行将产生最快的代码 .
另一个建议是,如果行的子集共享允许您这样做的特征,则将groupby与矢量化计算结合起来 .
我注意到Nick Crawford's回答后检查了
iterrows
,但发现它产生(索引,系列)元组 . 不确定哪个最适合你,但我最终使用itertuples
方法解决了我的问题,它产生了(index,row_value1 ...)元组 .还有
iterkv
,它遍历(列,系列)元组 .如果你有一个复杂的函数应用于单个列,你也可以做一个小的补充:
http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.apply.html
你有三个选择:
index(最简单):
使用iterrows(最常用):
随着itertuples(最快):
三个选项显示如下:
资料来源:neural-networks.io