尝试创建一个函数,该函数将求解向量或数组列的累积几何平均值。
我可以解决整个向量/列的几何平均值。只需要执行以下操作:
from scipy import stats
GM=stats.gmean(X)
print(GM)
在求解累积算术平均值时,我可以简单地运行pd.expanding_mean(x)来获得累积均值。
是否有一个我可以运行的功能,它会给出几何平均值的相同结果?
答案 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的回答。