我有一个多年的时间序列,想要按季节找到分位数。
在数值上,这很好用。但是,当我预计单个索引MultiIndex
时,我会得到Series
DataFrame
作为输出。
import pandas as pd
import numpy as np
rng = pd.date_range(start='2014-01-01', end='2016-01-01', freq='30T')
a_data = np.random.normal(loc=np.pi, scale=np.e, size=len(rng))
b_data = a_data - 5
df = pd.DataFrame(index=rng, data={'a': a_data, 'b': b_data})
grouped = df.groupby(pd.TimeGrouper(freq='QS-DEC'))
mult_idx_series = grouped.quantile(0.5)
mult_idx_series
显示MultiIndex
' d Series
:
2013-12-01 a 3.079999
b -1.920001
2014-03-01 a 3.126490
b -1.873510
我期望(和想要)与.median()相同的输出格式
median_df = grouped.median()
median_df
看起来像:
a b
2013-12-01 3.079999 -1.920001
2014-03-01 3.126490 -1.873510
我应该指出:
mult_idx_series.unstack(1)
来自我想要的格式我对不同的返回形状感到惊讶,并想了解推理。
答案 0 :(得分:5)
不同之处在于grouped.median()
调用优化(cythonized)median
聚合函数,而grouped.quantile()
调用通用包装器 apply 函数在群体上。
考虑一下:
In [56]: grouped.apply(lambda x: x.quantile(0.5))
Out[56]:
2013-12-01 a 3.175594
b -1.824406
2014-03-01 a 3.116556
b -1.883444
2014-06-01 a 3.222320
b -1.777680
2014-09-01 a 3.207015
b -1.792985
2014-12-01 a 3.114767
b -1.885233
2015-03-01 a 3.091952
b -1.908048
2015-06-01 a 3.220528
b -1.779472
2015-09-01 a 3.204990
b -1.795010
2015-12-01 a 3.108755
b -1.891245
dtype: float64
In [57]: grouped.agg(lambda x: x.quantile(0.5))
Out[57]:
a b
2013-12-01 3.175594 -1.824406
2014-03-01 3.116556 -1.883444
2014-06-01 3.222320 -1.777680
2014-09-01 3.207015 -1.792985
2014-12-01 3.114767 -1.885233
2015-03-01 3.091952 -1.908048
2015-06-01 3.220528 -1.779472
2015-09-01 3.204990 -1.795010
2015-12-01 3.108755 -1.891245
所以grouped.quantile()
执行应用,而不执行聚合。这样做的原因是quantile
也可以返回一个DataFrame(因此并不总是纯聚合),如果你一次计算多个分位数,例如grouped.quantile([0.1, 0.5, 0.9])
:
In [67]: grouped.quantile([0.1, 0.5, 0.9])
Out[67]:
a b
2013-12-01 0.1 -0.310566 -5.310566
0.5 3.131418 -1.868582
0.9 6.624399 1.624399
2014-03-01 0.1 -0.219992 -5.219992
0.5 3.173881 -1.826119
0.9 6.550259 1.550259
...