1

我将使用一个示例来解释我的问题:

A=[[1,2,10],[1,2,10],[3,4,5]]
B=[[1,2,30],[6,7,9]]

从这些列表列表中,我想创建第三个:

C=A+B

所以我得到:

C= [[1, 2, 10], [1, 2, 10], [3, 4, 5], [1, 2, 30], [6, 7, 9]]

请注意,在 中存在三个列表C,这些 [1, 2, 10], [1, 2, 10], [1, 2, 30]列表如果用 [x,y,z] 来描述,它们具有相同的 x,y 但不同的 z。

所以我想要这个新列表:

Averaged= [(1, 2, 16.666), (6, 7, 9), (3, 4, 5)]

我们从列表中只找到一次相同的 x,y

[1, 2, 30], [1, 2, 40], [1, 2, 50]

和相应 z 值的平均值(10+10+30)/3=16.666

我一开始尝试使用for循环,但最终尝试使用defaultdict.

我最终得到了这个保持一次 (x,y) 但添加而不是平均相应的 z 值:

from collections import defaultdict
Averaged=[]

A=[[1,2,10],[1,2,10],[3,4,5]]
B=[[1,2,30],[6,7,9]]
C=A+B
print "C=",C

ToBeAveraged= defaultdict(int)
for (x,y,z) in C:
    ToBeAveraged[(x,y)] += z
Averaged = [k + (v,) for k, v in ToBeAveraged.iteritems()]    

print 'Averaged=',Averaged

可以用defaultdict做到这一点吗?有任何想法吗?

4

2 回答 2

3

您需要先对数据进行排序:

>>> C = sorted(A + B)
>>> def avg(x):
        return sum(x) / len(x)

>>> [[avg(i) for i in zip(*y)] for x,y in 
     itertools.groupby(C, operator.itemgetter(0,1))]
[[1.0, 2.0, 16.666666666666668], [3.0, 4.0, 5.0], [6.0, 7.0, 9.0]]

如果您只想要平均值之前的组:

[list(y) for x,y in itertools.groupby(C, operator.itemgetter(0,1))]
于 2012-10-16T21:32:13.323 回答
2

在您的代码中,您没有除以观察次数。我更改了您的代码以收集给定对(x,y)的所有观察结果,然后取它们的平均值。应该有一个更有效的解决方案,但这应该有效。

from collections import defaultdict
Averaged=[]

A=[[1,2,10],[1,2,10],[3,4,5]]
B=[[1,2,30],[6,7,9]]
C=A+B
print "C=",C

def get_mean(x):
    return sum(ele for ele in x) / float(len(x))

ToBeAveraged= defaultdict(list)
for (x,y,z) in C:
    ToBeAveraged[(x,y)].append(z)
Averaged = [k + (get_mean(v),) for k, v in ToBeAveraged.iteritems()]    

print 'Averaged=',Averaged

结果:

C= [[1, 2, 10], [1, 2, 10], [3, 4, 5], [1, 2, 30], [6, 7, 9]]
Averaged= [(1, 2, 16.666666666666668), (6, 7, 9.0), (3, 4, 5.0)]
于 2012-10-16T21:46:02.887 回答