迭代求和
Iterative summation
我正在尝试编写一个 python 代码,允许我从第三个元素及其前两个元素开始,迭代地求和列表中三个元素的平均值。让我举个例子:
list = [1, 2, 3, 4, 5, 6, 7]
我要计算以下内容:
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
由于我对编程还很陌生,所以找不到将其放入函数中的有效方法。
你可以这样做:
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)
实现这一点的方法有很多,一种方法是递归。
该函数对列表的最后三个元素进行平均,并将结果添加到函数生成的结果中,列表缺少最后一个元素。如此继续,直到列表小于 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]))
另一种解决方案,您可以在其中指定要求和和平均的元素数量:
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
您可以使用 pandas 中的 rolling。
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)
您可以使用列表理解在一行中完成:
n = 3
avg = sum( [ sum(lst[i:i+n])/n for i in range(0, len(lst) - (n - 1)) ] )
print(avg) # 20.0
从数学上讲,这可以通过平均 3 个子列表的总和来获得:
L = [1, 2, 3, 4, 5, 6, 7]
r = (sum(L) + sum(L[1:-1]) + sum(L[2:-2]))/3 # 20.0
并且可以概括为 window 大小 w
:
w = 3
r = sum(sum(L[p:-p or None]) for p in range(w)) / w
它也可以通过使用项目位置来确定它们被添加到总数中的次数来实现,而无需生成子列表的开销:
r = sum(n*min(i+1,len(L)-i,w) for i,n in enumerate(L)) / w
这将是 3 种方法中内存效率最高的一种,因为它使用迭代器将数据提供给求和函数并且只遍历数据一次。
详细解释:
- 因为所有相加的平均值都是除以3,所以我们可以得出总和,最后除以3
- 第一个和最后一个位置的数字相加一次
- 倒数第二个数字相加两次
- 第三位到倒数第二的数字相加3次
视觉上:
(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
我正在尝试编写一个 python 代码,允许我从第三个元素及其前两个元素开始,迭代地求和列表中三个元素的平均值。让我举个例子:
list = [1, 2, 3, 4, 5, 6, 7]
我要计算以下内容:
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
由于我对编程还很陌生,所以找不到将其放入函数中的有效方法。
你可以这样做:
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)
实现这一点的方法有很多,一种方法是递归。 该函数对列表的最后三个元素进行平均,并将结果添加到函数生成的结果中,列表缺少最后一个元素。如此继续,直到列表小于 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]))
另一种解决方案,您可以在其中指定要求和和平均的元素数量:
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
您可以使用 pandas 中的 rolling。
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)
您可以使用列表理解在一行中完成:
n = 3
avg = sum( [ sum(lst[i:i+n])/n for i in range(0, len(lst) - (n - 1)) ] )
print(avg) # 20.0
从数学上讲,这可以通过平均 3 个子列表的总和来获得:
L = [1, 2, 3, 4, 5, 6, 7]
r = (sum(L) + sum(L[1:-1]) + sum(L[2:-2]))/3 # 20.0
并且可以概括为 window 大小 w
:
w = 3
r = sum(sum(L[p:-p or None]) for p in range(w)) / w
它也可以通过使用项目位置来确定它们被添加到总数中的次数来实现,而无需生成子列表的开销:
r = sum(n*min(i+1,len(L)-i,w) for i,n in enumerate(L)) / w
这将是 3 种方法中内存效率最高的一种,因为它使用迭代器将数据提供给求和函数并且只遍历数据一次。
详细解释:
- 因为所有相加的平均值都是除以3,所以我们可以得出总和,最后除以3
- 第一个和最后一个位置的数字相加一次
- 倒数第二个数字相加两次
- 第三位到倒数第二的数字相加3次
视觉上:
(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