简体   繁体   English

迭代求和

[英]Iterative summation

I'm trying to write a python code that allows me to iteratively sum up the average values of three elements of a list, starting with the third element and its two predecessors.我正在尝试编写一个 python 代码,它允许我迭代地总结列表中三个元素的平均值,从第三个元素及其两个前辈开始。 Let me give you an example:让我给你举个例子:

list = [1, 2, 3, 4, 5, 6, 7]

I want to calculate the following:我想计算以下内容:

sum_of_average_values = sum(1, 2, 3)/3 + sum(2, 3, 4)/3 + sum(3, 4, 5)/3 + sum(4, 5, 6)/3 + sum(5, 6, 7)/3 

Since I'm quite new to programming I couldn't find an effective way of putting this into a function.由于我对编程很陌生,我找不到将其放入 function 的有效方法。

You can do in this way:你可以这样做:

a = [1,2,3,4,5,6,7]
sum_of_average_values = 0
for i in range(0,len(a)-2):
    sum_of_average_values += sum(a[i:i+2])/3
print(sum_of_average_values)

Many ways to achieve this, one way is recursively.实现这一点的方法很多,其中一种方法是递归。 The function averages the last three elements of a list and adds the result to the result generated by the function with a list lacking the last element. function 平均列表的最后三个元素,并将结果添加到 function 生成的结果中,列表缺少最后一个元素。 Continues like this until the list is shorter than 3.像这样继续,直到列表短于 3。

def fn(l):
    if len(l) < 3: 
        return 0
    return sum(l[-3:])/3 + fn(l[:-1])

print(fn([1, 2, 3, 4, 5, 6, 7]))

Another solution where you can specify the amount of elements you want to sum up and average:另一种解决方案,您可以在其中指定要汇总和平均的元素数量:

l = [1, 2, 3, 4, 5, 6, 7]

def sum_avg(l, n):
  res = 0
  for i in range(n-1, len(l)):
    res += sum([l[j] for j in range(i, i-n, -1)])/n
    
  return res

print(sum_avg(l, 3))

--> 20.0 --> 20.0

You could use rolling from pandas.您可以使用 pandas 的滚动

import pandas as pd

num_list = [1, 2, 3, 4, 5, 6, 7]

average_sum = sum(pd.Series(num_list).rolling(3).mean().dropna())

print(average_sum)

Mathematically, this would could be obtain by averaging the sums of 3 sublists:从数学上讲,这可以通过平均 3 个子列表的总和来获得:

L = [1, 2, 3, 4, 5, 6, 7]  

r = (sum(L) + sum(L[1:-1]) + sum(L[2:-2]))/3  # 20.0

and can be generalized to a window size of w :并且可以推广到 window 大小w

w = 3
r = sum(sum(L[p:-p or None]) for p in range(w)) / w

It can also be implemented without the overhead of generating sublists by using item positions to determine the number of times they are added to the total:它也可以通过使用项目位置来确定它们被添加到总数中的次数来实现,而无需生成子列表的开销:

r = sum(n*min(i+1,len(L)-i,w) for i,n in enumerate(L)) / w

This would be the most memory-efficient of the 3 methods because it use an iterator to feed data to the sum function and only goes through the data once.这将是 3 种方法中内存效率最高的方法,因为它使用迭代器将数据提供给总和 function 并且只遍历数据一次。

Detailed explanation:详细解释:

  • Since all the averages that are added together are a division by 3, we can produce the total sum and divide by 3 at the end由于所有加在一起的平均值是除以 3,我们可以得出总和并在最后除以 3
  • the number at the first and last positions are added once第一个和最后一个位置的数字相加一次
  • the number at the second and penultimate positions are added twice第二个和倒数第二个位置的数字相加两次
  • The numbers from the third position up to the antepenultimate will be added 3 times从第三个 position 到倒数第二个的数字将相加 3 次

visually:视觉上:

(1   + 2   + 3)                             / 3
      (2   + 3   + 4)                       / 3
            (3   + 4   + 5)                 / 3
                  (4   + 5   + 6)           / 3
                        (5   + 6   + 7)     / 3

(1x1 + 2x2 + 3x3 + 4x3 + 5x3 + 6x2 + 7x1)   / 3 = 20.0

 n =  1   2   3   4   5   6   7   # value
 * =  1   2   3   3   3   2   1   # multiplier (times added)
      -------------------------
     (2,  4,  9, 12, 15, 12,  7) / 3 = 20.0

 i =  0   1   2   3   4   5   6   # index
      1   2   3   3   3   2   1   # min(i+1,len(L)-i,w) = multiplier

You can do in one line using list comprehension as:您可以使用列表理解在一行中执行以下操作:

n = 3
avg = sum( [ sum(lst[i:i+n])/n for i in range(0, len(lst) - (n - 1)) ] )
print(avg) # 20.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM