1


I'm doing some research and I'm implementing a moving average in Python based on this mathematical expression:

Moving Average for Peak Detection Where: n = sample and W1 = Window

I implemented like that:

def movingAverage(signal, window):

   sum = 0
   mAver = []
   k = int((window-1)/2)

   for i in np.arange(k, len(signal)-k):
       for ii in np.arange(i-k, i+k):
           sum = sum + signal[ii]
       #end-for
       mAver.append(sum / window)
       sum = 0
   #end-for

   zeros = [0]*k
   mAver = zeros + mAver + zeros

   return mAver

It work very well. But I'm trying to discover some way to implement the k variant to minimize the signal lost in beginning and in final (Now I'm using an list with zeros).


Can someone help me?

3 Answers 3

2

You could just use Pandas and specify center=True for your moving average.

import numpy as np
import pandas as pd

np.random.seed(0)

s = pd.Series(np.random.randn(7)).round(1)
moving_avg = s.rolling(window=3).mean(center=True)
>>> pd.concat([s, moving_avg.round(2)], axis=1).rename(columns={0: 'signal', 1: 'MA'})
   signal    MA
0     1.8   NaN
1     0.4  1.07  # 1.07 = (1.8 + 0.4 + 1.0) / 3
2     1.0  1.20  # 1.20 = (0.4 + 1.0 + 2.2) / 3
3     2.2  1.70
4     1.9  1.03
5    -1.0  0.63
6     1.0   NaN
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer, but I'm trying to implement it without using libraries. It can be good to implement in other languages.
1

You could use a filter with taps of all 1

import scipy as sp
import scipy.signal as sig

h = sp.ones(10)/10
y = sig.lfilter(h, 1, x)

4 Comments

Thanks for your answer, but I'm trying to implement it without using libraries. It can be good to implement in other languages.
It looks like you are already using numpy. Scipy includes numpy with additional packages thrown in for various signal and numeric prcessing functions.
If you want to implement the moving average this way, you have to set a to the length of b, so the window sum is divided and the result is the average, otherwise you end up multiplying the input by the window length.
I have just made the edit. You can plot the previous version vs. the corrected one to see the difference.
0

At the time I have found the following code:

def moving_average(samples, wind_len=1000):
    wind_len = int(wind_len)
    cumsum_samples = np.cumsum(samples)
    cumsum_diff = cumsum_samples[wind_len:] - cumsum_samples[:-wind_len]
    samples_average = cumsum_diff / float(wind_len)
    return samples_average

def my_cumsum(samples):
    for ind in range(1, len(samples)):
       samples[ind] = samples[ind] + samples[ind - 1]

1 Comment

Thanks for your answer, but I'm trying to implement it without using libraries. It can be good to implement in other languages.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.