0

Is there a way I could index through a numpy list just like how I would be able to within a normal list function. I want to go through 3 elements in the list moving up by one point every single time and summing all the slices. So it would go through 1,2,3 for the first sum and then it would go through 2,3,4 for the second sum etc. The code down below gives me a scalar error, is there a way I could perform the function below without using a for loop.

import numpy as np
n = 3 
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8,9, 10, 11,12, 13, 14, 15, 16, 17, 18, 19, 20, 21 ,22, 23, 24, 25])
start = np.arange(0, len(arr)-n, 1)
stop = np.arange(n-1, len(arr), 1)
sum_arr = np.sum(arr[start:stop])
3
  • [n:m] requires scalar values, not arrays. That's just true when used in arrays as in lists. Why didn't you use a list comprehension? Commented Jan 19, 2021 at 16:08
  • @hpaulj I dont want to use list comprehension with the for loop since it is slow. If possible I just want to use arrays. Commented Jan 19, 2021 at 16:37
  • For a start it's better to use something that's slow but works, rather trying some "I hope it works" guess! But there are a number of alternatives for moving-windows - as_strided, convolving, cumsum, etc. Commented Jan 19, 2021 at 17:19

2 Answers 2

1

I think this should work:

sum_arr = arr[1:-1] + arr[2:] + arr[:-2]

This creates an array that's two values shorter than arr because the last element in arr doesn't have two extra elements to create a sum with.

If you wanted the array to be of the same length as the original arr, you could append two extra zeros to the arr array like so:

arr = np.append(arr, [0, 0])
sum_arr = arr[1:-1] + arr[2:] + arr[:-2]
Sign up to request clarification or add additional context in comments.

2 Comments

Isnt there a better version where I can state the amount of arrays to sum the function with like instead of taking 3 numbers I would say 5 etc.
I have also updated it since I couldn't define the issue as well.
0

To sum a sliding range of n elements you can use convolve1d with all weights set to 1. Use 'constant' boundary mode with the default fill value of 0. As the filter window is centered by default you need to adjust the length of the result at both ends.

import numpy as np 
from scipy.ndimage import convolve1d

arr = np.arange(1,26)

for n in range(2,6):
   k,r = divmod(n, 2)
   print(n, convolve1d(arr, np.ones(n), mode='constant')[k+r-1:-k])

Result:

2 [ 3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49]
3 [ 6  9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72]
4 [ 10 14 18 22 26 30 34 38 42 46 50 54 58 62 66 70 74 78 82 86 90 94]
5 [ 15  20  25  30  35  40  45  50  55  60  65  70  75  80  85  90  95 100 105 110 115]

2 Comments

Is there a way I could iterate the function without a for loop. As I have explained on the details above I am trying to make the function run as fast as possible.
this is why i proposed a solution without a loop (the loop in the example is just for demonstration of different window sizes, i.e. for any given n, e.g. n=3 there will be no loop but just one call to convolve1d)

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.