我正在尝试对groupby的结果使用pct_change,以便计算跨越许多不同项的值的周期变化。
我的数据结构如下:
import numpy as np
arrays = [np.array([1,2,3,4,1,2,3,4]),np.array(['bar', 'bar', 'bar', 'bar', 'foo', 'foo', 'foo', 'foo'])]
s = pd.Series(np.array([100,101,102,103,200,201,202,203]), index=arrays)
s.name='values'
df = pd.DataFrame(s, index=arrays).sort_index()
df.index.names =['day','symbol']
我需要计算每天每个符号的百分比变化。当我运行这样的事情时:
df.groupby(level='symbol').values.diff()
我得到了正确的输出。但是当我运行时:
df.groupby(level='symbol').values.pct_change()
它返回错误的结果(将bar与foo比较)
我可以通过包装像这样的lambda来获得我正在寻找的东西:
my_func = lambda x: x.pct_change()
df.groupby(level='symbol').values.apply(my_func)
或通过这样做:
df.groupby(level='symbol').values.diff() / df.groupby(level='symbol').values.shift(1)
所以我真的只是想了解pct_change与其他pandas方法行为不同的原因。
答案 0 :(得分:1)
对于熊猫0.24.2上的多索引数据框,此解决方案对我有效:
pd.__version__
'0.24.2'
df.groupby(level='symbol')['values'].pct_change()
day symbol
1 bar NaN
foo NaN
2 bar 0.010000
foo 0.005000
3 bar 0.009901
foo 0.004975
4 bar 0.009804
foo 0.004950
Name: values, dtype: float64
答案 1 :(得分:0)
看起来我们必须使用.apply()
才能将它与多索引DF一起使用:
In [61]: df.groupby(level='symbol')['values'].apply(lambda x: x.pct_change())
Out[61]:
day symbol
1 bar NaN
foo NaN
2 bar 0.010000
foo 0.005000
3 bar 0.009901
foo 0.004975
4 bar 0.009804
foo 0.004950
Name: values, dtype: float64
PS对我来说这看起来像个错误 - IMO在按多指标级别分组时无法正常工作:
In [101]: g = df.groupby(level='symbol')
In [102]: g.values.pct_change??
Signature: g.values.pct_change(periods=1, fill_method='pad', limit=None, freq=None)
Source:
def pct_change(self, periods=1, fill_method='pad', limit=None, freq=None):
"""Calculate percent change of each value to previous entry in group"""
filled = getattr(self, fill_method)(limit=limit)
shifted = filled.shift(periods=periods, freq=freq)
return (filled / shifted) - 1
File: c:\users\max\anaconda3_5.0\envs\py36\lib\site-packages\pandas\core\groupby\groupby.py
Type: method
复制代码:
In [103]: filled = g['values'].pad(limit=None)
In [104]: shifted = filled.shift(periods=1, freq=None)
In [105]: (filled / shifted) - 1
Out[105]:
day symbol
1 bar NaN
foo 1.000000
2 bar -0.495000
foo 0.990099
3 bar -0.492537
foo 0.980392
4 bar -0.490099
foo 0.970874
Name: values, dtype: float64
我建议检查Pandas-Issues上是否已存在此类问题,如果该问题尚不存在,请打开一个新问题...