Reputation: 146
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
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
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
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