2017-05-01 20 views
0

ベクトルまたは配列の列の累積幾何平均を解く関数を作成しようとしています。累積幾何平均を計算する

のI /はcolumn..simply以下を行う必要があり、全体ベクトルの幾何平均解決することができる:累積演算を解く場合

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

を意味し、Iは単にpd.expanding_mean(X)に実行することができ累積平均を得る。

実行可能な関数がありますが、幾何平均の結果は同じですか?

答えて

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の答えを見てください。あなたのシリーズはかなり小さい場合

3

、あなたがすでに使用しているscipy.stats.gmeanでexpanding().applyを使用することができます。

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