2016-07-22 84 views
1

这看起来像一个简单的问题(和答案),但我遇到了麻烦。在熊猫市场的日常股票市场数据中寻找52周高点

问题:

我有一个数据帧熊猫全OHLC数据。我想在整个数据框中找到滚动的52周高点。

我的数据集是从雅虎。您可以提取相同的数据打倒folllowing代码来获得每日数据:

import pandas.io.data as web 
df = web.DataReader('SPX', 'yahoo', start, end) 

数据的尾巴,给出以下的输出:

    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 

要获得52周新高(滚动)我可以运行以下命令:

df["52weekhigh"] = pd.rolling_max(df.High, window=200, min_periods=1) 

我得到以下(部分彩色:

    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 

这给了我52周新高的值,因为新的高点进来,但我不是在这里使用200的粉丝。它应该是200还是201或220(当年“有大约”200个交易日)?

我可以重新采样数据到每周获取值,但然后我不能轻松回到我原来的每日数据(或我可以吗?)。

所以......这里的问题:

有没有办法对大熊猫dataframes运行rolling_max和窗口设置为'52周或类似的东西?如果没有,任何人都可以想到比上述更好的方法吗?

回答

4

如果您的数据有工作日频率,那么每周应该大致有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() 

enter image description here

+0

途径去加倍努力,同积:) – Alex

+0

感谢。你能帮我理解这与将窗口设置为200(或252或356或任何其他我想要的数字)有什么不同? –

+1

@ EricD.Brown:'window'参数影响每个计算中包含的 *行数*。如果您的DataFrame每周只有5个工作日,则 那么52周的窗口将完全对应于'window = 52 * 5'。但是,如果您的DataFrame 跳过一些假期(如新年),则每周可能不对应于5天的 天。通过使用'asfreq('D')'将频率扩展到几天,您每天会得到一行 行。所以你*保证* 52周完全符合 'window = 52 * 7'。 – unutbu