Python - 在嵌套列表中添加相同索引的元素,然后计算平均值
我有一个这样的列表:
[
[0, 5, -3, 5, 0, 0],
[-3, 0, 1, 0, 5, 0],
[1, 0, 5, 0, -5, 0],
[-3, 0, 3, 0, 0, 5]
]
我需要计算那些在同一个位置的元素的总和和平均值,然后把结果放到一个新的列表里。例如,所有内层列表中索引为0的项会被加在一起:
0 + (-3) + 1 + (-3) = -5
然后总和会除以数字的数量(0不算在内)来计算平均值:
average = -5/3 = -1.66666667
最后,这个平均值会被添加到一个新的列表中。
我原本期待结果会是这样的:
[
-1.66667,
5.0,
1.5,
5.0,
0.0,
5
]
我尝试了这个:
for i in range(0, len(rating_values)):
for j in range(0, len(rating_values[i])):
total = 0
count = 0
if rating_values[i][j] != 0:
total += rating_values[i][j]
count += 1
average_rating = total / count if count > 0 else 0
average_list.append(average_rating)
但我得到了这个:
[0, 5.0, -3.0, 5.0, 0, 0, -3.0, 0, 1.0, 0, 5.0, 0, 1.0, 0, 5.0, 0, -5.0, 0, -3.0, 0, 3.0, 0, 0, 5.0]
有没有办法让我在Python中只遍历那些内层列表中相同索引的项呢?
3 个回答
2
对于这种任务(多维数组),使用 numpy
会带来很大的好处。它不仅在处理大量数据时更高效,而且操作起来也更加自然。
使用 numpy
,你可以用一行代码就实现你想要的结果(y = ...
):
import numpy as np
x = np.array([
[0, 5, -3, 5, 0, 0],
[-3, 0, 1, 0, 5, 0],
[1, 0, 5, 0, -5, 0],
[-3, 0, 3, 0, 0, 5]
])
y = np.sum(x, axis=0) / np.sum(x != 0, axis=0)
print(y) # [-1.66666667 5. 1.5 5. 0. 5. ]
在这里,你进行的是“垂直”求和(axis=0
),然后把这个向量除以第0和第1列的垂直和的值(如果不等于0就算1,等于0就算0),也就是说,你是在用每一列中非零元素的数量来做除法。
2
你应该写一个独立的函数来计算你需要的值。这个函数会把一串整数加起来,计算出列表中零的个数,然后用总和去除以列表的长度减去零的个数。
这样做可能会导致出现一个叫做ZeroDivisionError的错误。
你可以使用zip()这个工具,方便地遍历你的输入列表。
data = [[0, 5, -3, 5, 0, 0], [-3, 0, 1, 0, 5, 0], [1, 0, 5, 0, -5, 0], [-3, 0, 3, 0, 0, 5]]
def average(e):
try:
return sum(e) / (len(e) - e.count(0))
except ZeroDivisionError:
pass
result = [average(e) for e in zip(*data)]
print(result)
输出:
[-1.6666666666666667, 5.0, 1.5, 5.0, 0.0, 5.0]
0
只需要稍微改动一下,你就能做到这一点。你应该先遍历每一列,然后再对每一列中的每一行进行处理。根据我看到的,你把求和和计数的变量放在了内层循环里,这样每处理一行它们就会重置一次。而且你在内层循环里也计算了平均值,这样就会导致每个索引出现多个结果。
rating_values = [[0, 5, -3, 5, 0, 0], [-3, 0, 1, 0, 5, 0], [1, 0, 5, 0, -5, 0], [-3, 0, 3, 0, 0, 5]]
average_list = []
# Loop through each index
for j in range(len(rating_values[0])): # Assumes all sublists are of equal length
total = 0
count = 0
# Loop through each list for the current index
for i in range(len(rating_values)):
if rating_values[i][j] != 0:
total += rating_values[i][j]
count += 1
# Compute the average; if count is 0, average is set to 0
average_rating = total / count if count > 0 else 0
average_list.append(round(average_rating, 5)) # rounding to 5 decimal places
print(average_list)