1

I'm trying to sum up elements from list in a moving range. For instance, when the user input a customized range 'n', list[0] to list[n] will be added up and stored in a new list, followed by list[1] to list[n+1] until the end. Finally the maximum number in the new list will print out. However, in my code, it seems that the elements are continuously summing up. Thanks a lot for your help.

The list is:

[5.8, 1.2, 5.8, 1.0, 6.9, 0.8, 6.0, 18.4, 18.6, 1.0, 0.8, 6.4, 12.2, 18.2, 1.4, 6.8, 41.8, 3.6, 5.2, 5.2, 4.6, 8.6, 16.6, 13.2, 9.6, 41.6, 37.2, 110.0, 30.0, 34.8, 24.6, 7.0, 13.4, 0.5, 37.0, 18.8, 20.4, 0.6, 6.4, 2.4, 1.0, 7.6, 6.6, 4.4, 2.4, 0.6, 3.2, 21.2, 28.2, 3.2, 2.4, 14.4, 0.6, 1.6, 4.4, 0.8, 0.6, 1.6, 1.0, 27.0, 52.6, 10.2, 1.0, 4.2]

My code:

days = int(input('Enter customized range: '))
n = np.arange(days) 
total = 0
count = 1
max_total = []



while (count + len(n) - 2) <= (len(rain_b) - 1):

    for i in range(count+len(n)-4, count+len(n)-2):
        total += rain_c[i]
    #print(rain_b[count+number-1])
    #total = sum([(rain_c(count+number-4)) : (count+number-2)])
        max_total.append(total)
    count += 1
    print(max_total)
AcK
  • 2,063
  • 2
  • 20
  • 27
Doris
  • 63
  • 4
  • 1
    Can you also include the desired and actual output for that input, or, if that's not possible, for a smaller example? Also, include the variables rain_b and rain_c so we can replicate your code. – kcsquared Sep 19 '21 at 00:57
  • You need to explain what each variable in your code represents. python doesn't require declaration of variables but it's still good practice. – Drew Sep 19 '21 at 01:01
  • Take a look at [Rolling or sliding window iterator](https://stackoverflow.com/questions/6822725/rolling-or-sliding-window-iterator) – Chris Sep 19 '21 at 01:03

4 Answers4

1

Since you're already using numpy, you can use np.convolve() with an array of ones with length n:

>>> n = 5
>>> x = np.arange(10)
>>> np.max(np.convolve(x, np.ones(n, dtype=x.dtype), mode="valid"))
35

This has the effect of performing the dot product of np.ones(n) with each n-element "window" of the array x. The sliding_window_view() from numpy.lib.stride_tricks is analogous and helps explain:

>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> windows = np.lib.stride_tricks.sliding_window_view(x, n)
>>> windows
array([[0, 1, 2, 3, 4],
       [1, 2, 3, 4, 5],
       [2, 3, 4, 5, 6],
       [3, 4, 5, 6, 7],
       [4, 5, 6, 7, 8],
       [5, 6, 7, 8, 9]])
>>> windows.sum(axis=1)
array([10, 15, 20, 25, 30, 35])
>>> np.convolve(x, np.ones(n, dtype=x.dtype), mode="valid")
array([10, 15, 20, 25, 30, 35])
ddejohn
  • 8,775
  • 3
  • 17
  • 30
-1

Try this (lst being your list and n being your range):

print(max(sum(lst[i:i+n+1]) for i in range(len(lst)-n)))

So for example:

>>> lst = [5.8, 1.2, 5.8, 1.0, 6.9, 0.8, 6.0, 18.4]
>>> n = 5
>>> print([sum(lst[i:i+n+1]) for i in range(len(lst)-n)])
[21.5, 21.7, 38.9]
>>> print(max(sum(lst[i:i+n+1]) for i in range(len(lst)-n)))
38.9
Riccardo Bucco
  • 13,980
  • 4
  • 22
  • 50
  • I don't think this is helpful for a beginner. – Drew Sep 19 '21 at 01:02
  • @Drew You're right sorry. Well, my answer is not difficult at all, it's a basic list comprehension. You're free to write something more long if you wish :) I like one liners – Riccardo Bucco Sep 19 '21 at 01:06
-1
  1. I would clean up your loop conditionals to be more clear and idiomatic.

  2. I believe the problem is that you're not zeroing total out between iterations.

  3. What are rain_b and rain_c? There should only be 1 input list and 1 output list.

  4. Why not store n as an integer instead of some object? I don't have numpy on my pc so I just removed that part.

Here's psudo code of how I would do this:

For x in range 0 up to len(input_list) - n:
     window_total = 0
     for y in range x to x+n-1:
         window_total += input_list[y]
     output_list.append(window_total)
Drew
  • 219
  • 3
  • 15
-1

Based on an iterator/array containing cumulative sum of numbers, you can get the rolling sum of n values by subtracting the cumulative values that are n positions behind. This approach has an O(N) time complexity (as opposed to computing the sum of every subrange, which is O(N x W) where W is the rolling window size)

Without numpy:

L = [5.8, 1.2, 5.8, 1.0, 6.9, 0.8, 6.0, 18.4, 18.6, 1.0, 0.8, 6.4, 12.2, 18.2, 1.4, 6.8, 41.8, 3.6, 5.2, 5.2, 4.6, 8.6, 16.6, 13.2, 9.6, 41.6, 37.2, 110.0, 30.0, 34.8, 24.6, 7.0, 13.4, 0.5, 37.0, 18.8, 20.4, 0.6, 6.4, 2.4, 1.0, 7.6, 6.6, 4.4, 2.4, 0.6, 3.2, 21.2, 28.2, 3.2, 2.4, 14.4, 0.6, 1.6, 4.4, 0.8, 0.6, 1.6, 1.0, 27.0, 52.6, 10.2, 1.0, 4.2]

n = 3

from itertools import accumulate

S = (a-b for a,b in zip(accumulate(L),accumulate([0]*n+L)))
print(max(S)) # 188.8

Using numpy

import numpy as np

L = np.array([5.8, 1.2, 5.8, 1.0, 6.9, 0.8, 6.0, 18.4, 18.6, 1.0, 0.8, 6.4, 12.2, 18.2, 1.4, 6.8, 41.8, 3.6, 5.2, 5.2, 4.6, 8.6, 16.6, 13.2, 9.6, 41.6, 37.2, 110.0, 30.0, 34.8, 24.6, 7.0, 13.4, 0.5, 37.0, 18.8, 20.4, 0.6, 6.4, 2.4, 1.0, 7.6, 6.6, 4.4, 2.4, 0.6, 3.2, 21.2, 28.2, 3.2, 2.4, 14.4, 0.6, 1.6, 4.4, 0.8, 0.6, 1.6, 1.0, 27.0, 52.6, 10.2, 1.0, 4.2])

n = 3

S = np.cumsum(L)
S[n:] -= S[:-n]
print(np.max(S)) # 188.8
Alain T.
  • 40,517
  • 4
  • 31
  • 51