There is a better way to create a rolling expading mean average function with numpy? [Python]

Recently I made a function to perform a rolling expanding mean average (not sure if it is the best term).In other words, I want to create a vector that is the sequential mean of the elements of another vector. For example, take the vector a = [1,2,2] , the resulting vector of this transformation will be b = [1,1.5,1.67].

I would like to know if there is a better way (no loop) to do it in Numpy.

This is the function I built:

def rolling_mean():
    results = []
    for n in range(1,len(X[:])+1):
        results.append(np.expand_dims(np.mean(X[:n],axis = 2),-1))
    return np.concatenate(results,axis = 2).shape

input:
array([107.82898848, 104.20672962, 101.11936848,  95.5392514 ,
        99.25907138,  88.30364673,  95.78052502,  91.88777602,
        92.94404695,  91.43067756,  97.80829905,  88.04812676,
        86.30507539,  84.34146879,  88.78491822,  83.77489231,
        82.72204444,  78.90779523,  78.73974639,  80.6807543 ,
        76.1253219 ,  80.17892777,  83.44848362,  85.16977125,
        88.63965418,  85.36051447,  84.49254174,  80.36832368,
        78.98803082,  80.7274235 ,  77.71078257,  75.89548114,
        73.07546659,  69.81760824,  67.27589733,  66.95237855,
        63.12044925,  63.58189569,  68.6789082 ,  70.92299637,
        69.96511396,  66.70713942,  64.04006182,  69.28454443,
        69.16610418,  66.76003564,  67.10493197,  74.06540923,
        74.19043057,  76.14746791])

output:

array([107.82898848, 106.01785905, 104.38502886, 102.17358449,
       101.59068187,  99.37617601,  98.86251159,  97.99066964,
        97.42993379,  96.83000816,  96.9189437 ,  96.17970895,
        95.42012176,  94.6287894 ,  94.23919799,  93.58517888,
        92.94617098,  92.16626121,  91.45960254,  90.92066013,
        90.21612021,  89.75988419,  89.48547547,  89.30565446,
        89.27901445,  89.12830291,  88.95660805,  88.64988361,
        88.31671627,  88.06373985,  87.72977348,  87.35995185,
        86.92708866,  86.42386865,  85.87678375,  85.35110583,
        84.75027727,  84.1932146 ,  83.79541187,  83.47360148,
        83.14412618,  82.75276935,  82.31759011,  82.02138452,
        81.73571163,  81.41015345,  81.10578704,  80.9591125 ,
        80.82097613,  80.72750597])

Upvotes: 0

Views: 143

Answers (1)

Pablo C
Pablo C

Reputation: 4761

Try something like this:

>>> a.cumsum() / np.arange(1, len(a) + 1)
array([1.        , 1.5       , 1.66666667])

just checking the larger one:

>>> a = np.array([107.82898848, 104.20672962, 101.11936848,  95.5392514 ,
        99.25907138,  88.30364673,  95.78052502,  91.88777602,
        92.94404695,  91.43067756,  97.80829905,  88.04812676,
        86.30507539,  84.34146879,  88.78491822,  83.77489231,
        82.72204444,  78.90779523,  78.73974639,  80.6807543 ,
        76.1253219 ,  80.17892777,  83.44848362,  85.16977125,
        88.63965418,  85.36051447,  84.49254174,  80.36832368,
        78.98803082,  80.7274235 ,  77.71078257,  75.89548114,
        73.07546659,  69.81760824,  67.27589733,  66.95237855,
        63.12044925,  63.58189569,  68.6789082 ,  70.92299637,
        69.96511396,  66.70713942,  64.04006182,  69.28454443,
        69.16610418,  66.76003564,  67.10493197,  74.06540923,
        74.19043057,  76.14746791])

>>> a.cumsum() / np.arange(1, len(a) + 1)
array([107.82898848, 106.01785905, 104.38502886, 102.1735845 ,
       101.59068187,  99.37617601,  98.86251159,  97.99066964,
        97.42993379,  96.83000816,  96.9189437 ,  96.17970895,
        95.42012176,  94.6287894 ,  94.23919799,  93.58517889,
        92.94617098,  92.16626121,  91.45960254,  90.92066013,
        90.21612021,  89.75988419,  89.48547547,  89.30565446,
        89.27901445,  89.12830291,  88.95660805,  88.64988361,
        88.31671627,  88.06373985,  87.72977348,  87.35995185,
        86.92708866,  86.42386865,  85.87678375,  85.35110583,
        84.75027727,  84.1932146 ,  83.79541187,  83.47360148,
        83.14412618,  82.75276935,  82.31759011,  82.02138452,
        81.73571163,  81.41015345,  81.10578704,  80.9591125 ,
        80.82097613,  80.72750597])

Upvotes: 3

Related Questions