Python 多指标滚动平均

Python 多指标滚动平均,python,pandas,multi-index,Python,Pandas,Multi Index,前言:我是新来的,但在这里和图书馆里搜寻了几个小时都没有成功。我也读过韦斯的书 我正在为一家对冲基金的股票市场数据建模,有一个简单的多索引数据框架,其中包含股票代码、日期(每日)和字段。这里的样本来自彭博社。3个月-2016年12月至2017年2月,3家股票公司(AAPL、IBM、MSFT) 当我计算每天的价格变化时,像这样,它似乎是有效的,只有第一天是NaN,因为它应该是: df.head(5) Out[7]: PX_LAST PX_V

前言:我是新来的,但在这里和图书馆里搜寻了几个小时都没有成功。我也读过韦斯的书

我正在为一家对冲基金的股票市场数据建模,有一个简单的多索引数据框架,其中包含股票代码、日期(每日)和字段。这里的样本来自彭博社。3个月-2016年12月至2017年2月,3家股票公司(AAPL、IBM、MSFT)

当我计算每天的价格变化时,像这样,它似乎是有效的,只有第一天是NaN,因为它应该是:

df.head(5)
Out[7]: 
                           PX_LAST  PX_VOLUME  px_change_%
Security Name  date                                       
AAPL US Equity 2016-12-01   109.49   37086862          NaN
               2016-12-02   109.90   26527997     0.003745
               2016-12-05   109.11   34324540    -0.007188
               2016-12-06   109.95   26195462     0.007699
               2016-12-07   111.03   29998719     0.009823
但每天30天的交易量却没有。在最初的29天内应为NaN,但在所有时间内均为NaN:

# daily change from 30 day volume - doesn't work
df['30_day_volume'] = df.groupby(level=0,group_keys=True)['PX_VOLUME'].rolling(window=30).mean()
df['volume_change_%'] = (df['PX_VOLUME'] - df['30_day_volume']) / df['30_day_volume']

df.iloc[:,3:].tail(40)
Out[12]: 
                           30_day_volume  volume_change_%
Security Name  date                                      
MSFT US Equity 2016-12-30            NaN              NaN
               2017-01-03            NaN              NaN
               2017-01-04            NaN              NaN
               2017-01-05            NaN              NaN
               2017-01-06            NaN              NaN
               2017-01-09            NaN              NaN
               2017-01-10            NaN              NaN
               2017-01-11            NaN              NaN
               2017-01-12            NaN              NaN
               2017-01-13            NaN              NaN
               2017-01-17            NaN              NaN
               2017-01-18            NaN              NaN
               2017-01-19            NaN              NaN
               2017-01-20            NaN              NaN
               2017-01-23            NaN              NaN
               2017-01-24            NaN              NaN
               2017-01-25            NaN              NaN
               2017-01-26            NaN              NaN
               2017-01-27            NaN              NaN
               2017-01-30            NaN              NaN
               2017-01-31            NaN              NaN
               2017-02-01            NaN              NaN
               2017-02-02            NaN              NaN
               2017-02-03            NaN              NaN
               2017-02-06            NaN              NaN
               2017-02-07            NaN              NaN
               2017-02-08            NaN              NaN
               2017-02-09            NaN              NaN
               2017-02-10            NaN              NaN
               2017-02-13            NaN              NaN
               2017-02-14            NaN              NaN
               2017-02-15            NaN              NaN
               2017-02-16            NaN              NaN
               2017-02-17            NaN              NaN
               2017-02-21            NaN              NaN
               2017-02-22            NaN              NaN
               2017-02-23            NaN              NaN
               2017-02-24            NaN              NaN
               2017-02-27            NaN              NaN
               2017-02-28            NaN              NaN
由于熊猫似乎是专门为金融而设计的,我很惊讶这并不简单

编辑:我也尝试过其他方法

  • 尝试将其转换为面板(3D),但除了转换为数据帧并返回外,没有发现任何Windows内置函数,因此没有任何优势
  • 尝试创建透视表,但找不到只引用多索引的第一级的方法<代码>df.index.levels[0]或
    …levels[1]
    不起作用

谢谢

你能试试下面的方法看看是否有效吗

df['30_day_volume'] = df.groupby(level=0)['PX_VOLUME'].rolling(window=30).mean().values

df['volume_change_%'] = (df['PX_VOLUME'] - df['30_day_volume']) / df['30_day_volume']

当使用pandas_datareader修改datareader多重索引的groupby操作的索引级别时,我可以验证Allen的答案是否有效

import pandas_datareader.data as web
import datetime

start = datetime.datetime(2016, 12, 1)
end = datetime.datetime(2017, 2, 28)
data = web.DataReader(['AAPL', 'IBM', 'MSFT'], 'yahoo', start, end).to_frame()

data['30_day_volume'] = data.groupby(level=1).rolling(window=30)['Volume'].mean().values

data['volume_change_%'] = (data['Volume'] - data['30_day_volume']) / data['30_day_volume']

# double-check that it computed starting at 30 trading days. 
data.loc['2017-1-17':'2017-1-30']
原始海报可能会尝试编辑以下行:

df['30_day_volume'] = df.groupby(level=0,group_keys=True)['PX_VOLUME'].rolling(window=30).mean()
使用mean().值进行以下操作:


如果没有此选项,数据将无法正确对齐,这将导致NaN。

正常工作,谢谢!但是我很好奇它背后的解释-为什么添加
.values
?似乎
values
是数据帧的一个属性,返回数据帧的NumPy表示形式,正如Wes自己一样,GroupBy对象本身就是一个数据帧。GroupBy和rolling函数创建了一个多索引系列,其中包含重复的索引键,这在分配给DF列时造成了问题。.values属性只从可以毫无问题地分配给DF列的序列中取出值。非常好,我感谢您的澄清。
df['30_day_volume'] = df.groupby(level=0,group_keys=True)['PX_VOLUME'].rolling(window=30).mean()
df['30_day_volume'] = df.groupby(level=0,group_keys=True)['PX_VOLUME'].rolling(window=30).mean().values