36

我有一个列表列表:类似于:

data = [[240, 240, 239],
        [250, 249, 237], 
        [242, 239, 237],
        [240, 234, 233]]

我想平均一下

[average_column_1, average_column_2, average_column_3]

我的一段代码不是很优雅。这是遍历列表的天真方式,将总和保存在单独的容器中,然后除以元素的数量。

我认为有一种pythonic方法可以做到这一点。有什么建议么?谢谢

4

5 回答 5

67

纯 Python:

from __future__ import division
def mean(a):
    return sum(a) / len(a)
a = [[240, 240, 239],
     [250, 249, 237], 
     [242, 239, 237],
     [240, 234, 233]]
print map(mean, zip(*a))

印刷

[243.0, 240.5, 236.5]

数字货币:

a = numpy.array([[240, 240, 239],
                 [250, 249, 237], 
                 [242, 239, 237],
                 [240, 234, 233]])
print numpy.mean(a, axis=0)

蟒蛇 3:

from statistics import mean
a = [[240, 240, 239],
     [250, 249, 237], 
     [242, 239, 237],
     [240, 234, 233]]
print(*map(mean, zip(*a)))
于 2012-06-06T18:07:24.180 回答
31
data = [[240, 240, 239],
        [250, 249, 237], 
        [242, 239, 237],
        [240, 234, 233]]
avg = [float(sum(col))/len(col) for col in zip(*data)]
# [243.0, 240.5, 236.5]

这是有效的,因为zip(*data)会给你一个包含列分组的列表,float()只有在 Python 2.x 上才需要调用,除非使用整数除法,否则它使用整数除法from __future__ import division

于 2012-06-06T18:07:59.913 回答
14

使用zip(),像这样:

averages = [sum(col) / float(len(col)) for col in zip(*data)]

zip()接受多个可迭代参数,并返回这些可迭代对象的切片(作为元组),直到其中一个可迭代对象不能再返回任何内容。实际上,它执行转置操作,类似于矩阵。

>>> data = [[240, 240, 239],
...         [250, 249, 237], 
...         [242, 239, 237],
...         [240, 234, 233]]

>>> [list(col) for col in zip(*data)]
[[240, 250, 242, 240],
 [240, 249, 239, 234],
 [239, 237, 237, 233]]

通过sum()对这些切片中的每一个进行执行,您可以有效地获得按列计算的总和。只需除以列的长度即可获得平均值。

旁白:在 Python 2.x 中,整数除法默认使用小数,这就是为什么float()调用将结果“提升”为浮点类型的原因。

于 2012-06-06T18:07:23.843 回答
8
import numpy as np

data = [[240, 240, 239],
        [250, 249, 237], 
        [242, 239, 237],
        [240, 234, 233]]

np.mean(data, axis=0)
# array([ 243. ,  240.5,  236.5])

似乎工作。

于 2017-09-11T14:17:16.850 回答
0

您可以使用mapzip

list(map(lambda x: sum(x)/len(x), zip(*data)))
[243.0, 240.5, 236.5]
于 2020-07-23T14:14:40.990 回答