understorey
understorey

Reputation: 146

Moving Average Function

I am learning Python and one of the exercises from the course I am taking is to create a function that calculates the moving average of all elements in a vector, given a window of elements. The only exceptional cases is near the edges where there are not enough neighbours then the edge value must be repeated. I wrote the following function, which is not working:

%reset -f
def moving_window_average(x, n_neighbors):
    mavg=[]
    i=0
    while i<=len(x):
        sumv=[x[i]]
        j = n_neighbors
        while j>0:
            if  (i-j)<0:
                sumv.append(x[i])
                sumv.append(x[i+j])
                j-=1
            elif (i+j)>len(x):
                sumv.append(x[i])
                sumv.append(x[i-j])
                j-=1
            else:
                sumv.append(x[i-j])
                sumv.append(x[i+j])
                j-=1
        mavg_i=sum(sumv)/len(sumv)
        mavg.append(mavg_i)
        i+=1
    return mavg
x = [0,10,5,3,1,5]
print(moving_window_average(x, 1))

But when I run line by line it works (like below) it works fine for me

mavg=[]
i=0
#while i<=len(x):
i<=len(x)
sumv=[x[i]]
j=1
#while j>0
j>0
#
(i-j)<0
sumv.append(x[i])
sumv.append(x[i+j])
j-=1
#
(i+j)>len(x)
sumv.append(x[i])
sumv.append(x[i-j])
j-=1
# else
sumv.append(x[i-j])
sumv.append(x[i+j])
j-=1
mavg_i=sum(sumv)/len(sumv)
mavg.append(mavg_i)
i+=1

Can someone please help me? I reckon the solution must be rather simple, but I cannot understand what is wrong in my function. Thank you.

Upvotes: 0

Views: 223

Answers (3)

Salil Tamboli
Salil Tamboli

Reputation: 118

In your code, when you are using while loop, you are making a small mistake. Since you are typically in a while loop and you are checking a list length as a reference to limit loop count, one needs to be very careful. In python element count starts with zero, so you should stop before one value or count less than the length of any list len(list).

Just remove = sign from outer while loop and your code will work.

def moving_window_average(x, n_neighbors):
    mavg=[]
    i=0
    while i < len(x):
        sumv=[x[i]]
            ...
            ...

Note : Use for loop here, it's safer than while loop.

Upvotes: 1

The Javatar
The Javatar

Reputation: 719

First of all you shouldn't have while i<=len(x): since the index len(x) is outside the range of valid values in x.
You have some logic error when the neighbor falls out of the array. That is instead of sumv.append(x[i]) when (i-j)<0 you should append x[0]. The same with the second condition where you should take the last element x[-1] (the condition here should be (i+j) >= len(x)).
Also, since you are doing a course you should strive to write more pythonic code, try to replace the while with a for first, and see if you can get rid of that too, afterwards.
Your complexity right now is O(N*K) where N is the length of the array and K is the number of neighbors, it can be reduced to just O(N) ;)

Upvotes: 1

emilioho2020
emilioho2020

Reputation: 102

you're going out of bounds.

sumv.append(x[i+j]) IndexError: list index out of range

You are checking if i+j > len(x) But it should be i+j >= len(x) as the indexing starts from 0 and not from 1.

Also, I see you are learning python. While your program might work, mess around with it in order to make it shorter: Use for loops to iterate over lists, for example

Upvotes: 0

Related Questions