Python 在DataFrame对象上使用滚动应用
我试图在滚动的基础上计算成交量加权平均价格 要做到这一点,我有一个函数vwap,它可以为我实现这一点,如下所示:Python 在DataFrame对象上使用滚动应用,python,pandas,Python,Pandas,我试图在滚动的基础上计算成交量加权平均价格 要做到这一点,我有一个函数vwap,它可以为我实现这一点,如下所示: def vwap(bars): return ((bars.Close*bars.Volume).sum()/bars.Volume.sum()).round(2) 当我尝试将此函数与rolling_apply一起使用时,如图所示,我得到一个错误: import pandas.io.data as web bars = web.DataReader('AAPL','yaho
def vwap(bars):
return ((bars.Close*bars.Volume).sum()/bars.Volume.sum()).round(2)
当我尝试将此函数与rolling_apply一起使用时,如图所示,我得到一个错误:
import pandas.io.data as web
bars = web.DataReader('AAPL','yahoo')
print pandas.rolling_apply(bars,30,vwap)
AttributeError: 'numpy.ndarray' object has no attribute 'Close'
这个错误对我来说很有意义,因为rolling_apply不需要数据系列或数据数组作为输入,也不需要数据帧。。我做这件事的方式
有没有一种方法可以使用滚动应用于数据帧来解决我的问题?这不是直接启用的,但您可以这样做
In [29]: bars
Out[29]:
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 942 entries, 2010-01-04 00:00:00 to 2013-09-30 00:00:00
Data columns (total 6 columns):
Open 942 non-null values
High 942 non-null values
Low 942 non-null values
Close 942 non-null values
Volume 942 non-null values
Adj Close 942 non-null values
dtypes: float64(5), int64(1)
window=30
In [30]: concat([ (Series(vwap(bars.iloc[i:i+window]),
index=[bars.index[i+window]])) for i in xrange(len(df)-window) ])
Out[30]:
2010-02-17 203.21
2010-02-18 202.95
2010-02-19 202.64
2010-02-22 202.41
2010-02-23 202.19
2010-02-24 201.85
2010-02-25 201.65
2010-02-26 201.50
2010-03-01 201.31
2010-03-02 201.35
2010-03-03 201.42
2010-03-04 201.09
2010-03-05 200.95
2010-03-08 201.50
2010-03-09 202.02
...
2013-09-10 485.94
2013-09-11 487.38
2013-09-12 486.77
2013-09-13 487.23
2013-09-16 487.20
2013-09-17 486.09
2013-09-18 485.52
2013-09-19 485.30
2013-09-20 485.37
2013-09-23 484.87
2013-09-24 485.81
2013-09-25 486.41
2013-09-26 486.07
2013-09-27 485.30
2013-09-30 484.74
Length: 912
[29]中的:条
出[29]:
日期时间索引:942条条目,2010-01-04 00:00:00至2013-09-30 00:00:00
数据列(共6列):
打开942个非空值
高942非空值
低942非空值
关闭942个非空值
卷942非空值
Adj Close 942非空值
数据类型:float64(5)、int64(1)
窗口=30
[30]中的concat([(系列)(vwap(bar.iloc[i:i+window]),
索引=[bar.index[i+窗口]]),用于X范围内的i(len(df)-窗口)])
出[30]:
2010-02-17 203.21
2010-02-18 202.95
2010-02-19 202.64
2010-02-22 202.41
2010-02-23 202.19
2010-02-24 201.85
2010-02-25 201.65
2010-02-26 201.50
2010-03-01 201.31
2010-03-02 201.35
2010-03-03 201.42
2010-03-04 201.09
2010-03-05 200.95
2010-03-08 201.50
2010-03-09 202.02
...
2013-09-10 485.94
2013-09-11 487.38
2013-09-12 486.77
2013-09-13 487.23
2013-09-16 487.20
2013-09-17 486.09
2013-09-18 485.52
2013-09-19 485.30
2013-09-20 485.37
2013-09-23 484.87
2013-09-24 485.81
2013-09-25 486.41
2013-09-26 486.07
2013-09-27 485.30
2013-09-30 484.74
长度:912
一个经过清理的版本供参考,希望索引正确:
def myrolling_apply(df, N, f, nn=1):
ii = [int(x) for x in arange(0, df.shape[0] - N + 1, nn)]
out = [f(df.iloc[i:(i + N)]) for i in ii]
out = pandas.Series(out)
out.index = df.index[N-1::nn]
return(out)
修改@Mathdick的答案,使其包含
na_fill
。还要注意,函数f
需要返回一个值,这不能返回具有多列的数据帧
def rolling_apply_df(dfg, N, f, nn=1, na_fill=True):
ii = [int(x) for x in np.arange(0, dfg.shape[0] - N + 1, nn)]
out = [f(dfg.iloc[i:(i + N)]) for i in ii]
if(na_fill):
out = pd.Series(np.concatenate([np.repeat(np.nan, N-1),np.array(out)]))
out.index = dfg.index[::nn]
else:
out = pd.Series(out)
out.index = dfg.index[N-1::nn]
return(out)
很好的解决方案,对我很有帮助!但问题是:在您的列表理解中,您不会使用bars.iloc[i:i+window+1],因为.iloc排除了上界吗?在您的代码中,在以bars.iloc[i+window-1]结尾的计算中仅使用29个值,而bars.index[i+window]用作标签。在这种类型的计算中,我想您会希望计算中包含bar.iloc[I+window]。的可能重复项。看我的答案。