在熊猫的每日股市数据上找到连续52周新高

Eri*_*own 2 python pandas

这似乎是一个简单的问题(和答案),但是我遇到了麻烦。

问题:

我有一个充满OHLC数据的熊猫数据框。我想在整个数据框中找到52周以来的最高滚动。

我的数据集来自雅虎。您可以使用以下代码提取相同的数据以获取每日数据:

import pandas.io.data as web
df = web.DataReader('SPX', 'yahoo', start, end)
Run Code Online (Sandbox Code Playgroud)

数据的尾部给出以下输出:

                 Open        High         Low       Close     Volume  
Date                                                                    
2016-07-15  216.779999  217.009995  215.309998  215.830002  107155400   
2016-07-18  215.970001  216.600006  215.669998  216.410004   58725900   
2016-07-19  215.919998  216.229996  215.630005  216.190002   54345700   
2016-07-20  216.190002  217.369995  216.190002  217.089996   58159500   
2016-07-21  216.960007  217.220001  215.750000  216.270004   66070000 
Run Code Online (Sandbox Code Playgroud)

为了达到52周的最高水平(滚动),我可以运行以下命令:

df["52weekhigh"] = pd.rolling_max(df.High, window=200, min_periods=1)
Run Code Online (Sandbox Code Playgroud)

我得到以下内容(一些上校:

                 High  52weekhigh
Date                              
2016-07-15  217.009995  217.009995
2016-07-18  216.600006  217.009995
2016-07-19  216.229996  217.009995
2016-07-20  217.369995  217.369995
2016-07-21  217.220001  217.369995
Run Code Online (Sandbox Code Playgroud)

随着新高的到来,这给了我52周高点的价值,但是我不喜欢在这里使用200。是200还是201或220(一年中大约有200个交易日)?

我可以每周对数据进行重新采样以获取值,但后来我无法轻松地恢复到原始的每日数据(或者可以吗?)。

所以...这是一个问题:

有没有办法在pandas数据帧上运行rolling_max,并将窗口设置为“ 52周”或类似的方法?如果没有,那么谁能想到比上述更好的方法呢?

unu*_*tbu 5

如果您的数据具有工作日频率,则每周应大约有5行。因此52周大致相当于window=52*5

当然,由于假期可能还会缺少其他几天。为了更准确,您可以使用asfreq('D')将频率从工作日更改为实际日。然后,您可以使用一个滚动窗口,其大小为52*7

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
np.random.seed(2016)

N = 1000
index = pd.date_range('2000-1-1', periods=N, freq='B')
data = (np.random.random((N, 1))-0.5).cumsum(axis=0)
df = pd.DataFrame(data, index=index, columns=['price'])
# result = pd.rolling_max(df.asfreq('D'), window=52*7, min_periods=1)   # for older versions of Pandas
result = df.asfreq('D').rolling(window=52*7, min_periods=1).max()
result = result.rename(columns={'price':'rolling max'})

ax = df.plot()
result.plot(ax=ax)
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • @EricD.Brown:“窗口”参数影响每个计算中包含的*行*数。如果您的 DataFrame 每周正好有 5 个工作日,那么 52 周的窗口将正好对应“window=52*5”。但是,如果您的 DataFrame 跳过一些假期(例如新年),那么每周可能不对应 5 天。通过使用 asfreq('D') 将频率扩展到天,您将每天获得一行。因此,您*保证* 52 周恰好对应于“window=52*7”。 (2认同)