使用pandas循环数据帧的最有效方法是什么?

2024-05-23 22:51:52 发布

您现在位置:Python中文网/ 问答频道 /正文

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

例如,我正在使用来自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..

这是最有效的方法吗?考虑到pandas对速度的关注,我假设一定有一些特殊的函数来迭代这些值,迭代的方式是检索索引(可能通过生成器来提高内存效率)?df.iteritems不幸的是,只会逐列迭代。


Tags: csv数据pandasdfclosedate顺序on
3条回答

熊猫是基于核阵列的。 加快使用NumPy数组的速度的关键是一次对整个数组执行操作,而不是逐行或逐项执行。

例如,如果close是一个一维数组,并且您希望日百分比变化

pct_change = close[1:]/close[:-1]

这将把百分比变化的整个数组作为一个语句计算,而不是

pct_change = []
for row in close:
    pct_change.append(...)

所以尽量避免Python循环for i, row in enumerate(...),并且 考虑如何在整个数组(或数据帧)上执行运算,而不是逐行执行。

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

for index, row in df.iterrows():

    # do some logic here

或者,如果您想更快地使用itertuples()

但是,unutbu建议使用numpy函数来避免对行进行迭代,这将产生最快的代码。

与前面提到的一样,pandas对象在一次处理整个数组时效率最高。不过,对于那些真正需要循环通过pandas数据帧来执行某些操作的人,比如我,我至少找到了三种方法。我做了一个简短的测试,看看这三种方法中哪一种最省时。

t = pd.DataFrame({'a': range(0, 10000), 'b': range(10000, 20000)})
B = []
C = []
A = time.time()
for i,r in t.iterrows():
    C.append((r['a'], r['b']))
B.append(time.time()-A)

C = []
A = time.time()
for ir in t.itertuples():
    C.append((ir[1], ir[2]))    
B.append(time.time()-A)

C = []
A = time.time()
for r in zip(t['a'], t['b']):
    C.append((r[0], r[1]))
B.append(time.time()-A)

print B

结果:

[0.5639059543609619, 0.017839908599853516, 0.005645036697387695]

这可能不是测量时间消耗的最好方法,但对我来说很快。

以下是一些利弊:

  • .iterrows():返回单独变量中的索引项和行项,但速度明显较慢
  • .itertuples():比.iterrows()快,但返回索引和行项,ir[0]是索引
  • zip:最快,但无法访问行的索引

相关问题 更多 >