Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于前几行的数据帧计算速度非常慢_Python_Pandas_Performance - Fatal编程技术网

Python 基于前几行的数据帧计算速度非常慢

Python 基于前几行的数据帧计算速度非常慢,python,pandas,performance,Python,Pandas,Performance,我正在计算股票价格的RSI值,其中当前行的结果需要前一行。我目前正在通过循环完整的数据帧来完成这项工作,因为有很多条目需要花费很多时间(在我的电脑上执行时间约为15秒) 有什么方法可以改进代码吗 import pandas as pd from pathlib import Path filename = Path("Tesla.csv") test = pd.read_csv(filename) data = pd.DataFrame(test[["Date&

我正在计算股票价格的RSI值,其中当前行的结果需要前一行。我目前正在通过循环完整的数据帧来完成这项工作,因为有很多条目需要花费很多时间(在我的电脑上执行时间约为15秒)

有什么方法可以改进代码吗

import pandas as pd
from pathlib import Path


filename = Path("Tesla.csv")
test = pd.read_csv(filename)
data = pd.DataFrame(test[["Date","Close"]])
data["Change"] = (data["Close"].shift(-1)-data["Close"]).shift(1)
data["Gain"] = 0.0
data["Loss"] = 0.0
data.loc[data["Change"] >= 0, "Gain"] = data["Change"]
data.loc[data["Change"] <= 0, "Loss"] = data["Change"]*-1
data.loc[:, "avgGain"] = 0.0
data.loc[:, "avgLoss"] = 0.0
data["avgGain"].iat[14] = data["Gain"][1:15].mean()
data["avgLoss"].iat[14] = data["Loss"][1:15].mean()


for index in data.iterrows():
    data.loc[15:, "avgGain"] = (data.loc[14:, "avgGain"].shift(1)*13 + data.loc[15:, "Gain"])/14
    data.loc[15:, "avgLoss"] = (data.loc[14:, "avgLoss"].shift(1)*13 + data.loc[15:, "Loss"])/14
将熊猫作为pd导入
从pathlib导入路径
文件名=路径(“Tesla.csv”)
test=pd.read\u csv(文件名)
数据=pd.DataFrame(测试[[“日期”,“关闭”]])
数据[“更改”]=(数据[“关闭”]。移位(-1)-数据[“关闭”])。移位(1)
数据[“增益”]=0.0
数据[“损失”]=0.0
data.loc[数据[“更改”]>=0,“增益”]=data[“更改”]

data.loc[data[“Change”]“itertuples”比“iterrows”更快,矢量化操作通常在性能方面表现最好

在这里,您可以使用窗口大小为14的
rolling
方法计算14天内的平均收益和损失(滚动平均值)

%%timeit
数据[“平均值”]。iat[14]=数据[“增益”][1:15]。平均值()
数据[“avgLoss”]。iat[14]=数据[“损失”][1:15]。平均值()
对于data.iterrows()中的索引:
data.loc[15:,“avgGain”]=(data.loc[14:,“avgGain”].shift(1)*13+data.loc[15:,“Gain”])/14
data.loc[15:,“avgLoss”]=(data.loc[14:,“avgLoss”].shift(1)*13+data.loc[15:,“Loss”])/14
每个回路1.12 s±3.73 ms(7次运行的平均值±标准偏差,每个回路1次)

%%timeit
数据['avgGain_alt']=数据['Gain'].滚动(窗口=14).mean().填充(0)
数据['avgLos_alt']=数据['Gain'].滚动(窗口=14).mean().填充(0)
每个回路1.38 ms±2.31µs(7次运行的平均值±标准偏差,每个1000个回路)

data.head(15)

使用矢量化操作来计算移动平均值比使用循环计算快大约10倍


但是请注意,对于第一行之后的平均值,您的代码中也存在一些计算错误。

您可以通过使用而不是对行进行迭代来加快速度。不过,我并不完全清楚这个循环试图实现什么。
index
从未实际使用过。看起来两行可以实现相同的效果你能用一个小数据集提供一个可复制的例子吗?我用一个例子更新了我的第一篇文章。你能手动将
tesla.csv
中的一些数据输入到脚本中,或者将其上传到互联网上的某个地方,比如谷歌硬盘电子表格中。它仍然无法复制。我已经看到了滚动函数(与mean函数结合使用),但它没有给出所需的相同值。很容易说,我需要的函数是:newAvgGainValue=(lastAvgGainValue*13+currentGainValue)/14,这会导致即使是第一个值对最后一个值的影响。这对imho来说没有多大意义,但它是如何计算的。(好的,还有其他一些方法来计算RSI的滚动平均值,但比较hompage使用上述计算)