Python - 在嵌套列表中添加相同索引的元素,然后计算平均值

2 投票
3 回答
62 浏览
提问于 2025-04-13 18:38

我有一个这样的列表:

[
  [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)

撰写回答