计算累积几何平均数

时间:2017-05-01 01:33:34

标签: python pandas numpy scipy mean

尝试创建一个函数,该函数将求解向量或数组列的累积几何平均值。

我可以解决整个向量/列的几何平均值。只需要执行以下操作:

from scipy import stats
GM=stats.gmean(X)
print(GM)

在求解累积算术平均值时,我可以简单地运行pd.expanding_mean(x)来获得累积均值。

是否有一个我可以运行的功能,它会给出几何平均值的相同结果?

2 个答案:

答案 0 :(得分:3)

如果你的系列很小,你可以将expanding().apply与你已经使用的scipy.stats.gmean一起使用:

In [26]: s = pd.Series(range(1,10))

In [27]: s.expanding().apply(stats.gmean)
Out[27]: 
0    1.000000
1    1.414214
2    1.817121
3    2.213364
4    2.605171
5    2.993795
6    3.380015
7    3.764351
8    4.147166
dtype: float64

但对于更长的系列来说,这将是非常低效的:

In [30]: %time egm = pd.concat([s]*1000).expanding().apply(stats.gmean)
CPU times: user 6.5 s, sys: 4 ms, total: 6.5 s
Wall time: 6.53 s

所以你可能想要制作一个自定义函数,比如

def expanding_gmean_log(s):
    return np.exp(np.log(s).cumsum() / (np.arange(len(s))+1))

我们在日志空间中工作,而不是s.cumprod() ** (1/(np.arange(len(s))+1))之类的工作,以帮助避免中间产品溢出。

In [52]: %timeit egm = expanding_gmean_log(pd.concat([s]*1000))
10 loops, best of 3: 71 ms per loop

In [53]: np.allclose(expanding_gmean_log(pd.concat([s]*1000)),
                     pd.concat([s]*1000).expanding().apply(stats.gmean))
Out[53]: True

答案 1 :(得分:2)

您可以使用gmean公式的矢量化实现。例如,

In [159]: x
Out[159]: array([10,  5, 12, 12,  2, 10])

In [160]: x.cumprod()**(1/np.arange(1., len(x)+1))
Out[160]: 
array([ 10.        ,   7.07106781,   8.43432665,   9.2115587 ,
         6.78691638,   7.23980855])

以下是使用gmean()和列表理解的相同结果:

In [161]: np.array([gmean(x[:k]) for k in range(1, len(x)+1)])
Out[161]: 
array([ 10.        ,   7.07106781,   8.43432665,   9.2115587 ,
         6.78691638,   7.23980855])

如果x.cumprod()可能会溢出,您可以使用gmean的对数;请参阅@ DSM的回答。