【问题标题】:Python: Finding number of same lists occurrences and averagingPython:查找相同列表出现的次数并求平均值
【发布时间】:2012-10-16 21:25:49
【问题描述】:

我会用一个例子来解释我的问题:

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 做到这一点吗?有什么想法吗?

【问题讨论】:

  • 如果 x 和 z 相同但 y 不同怎么办?
  • 不,只有 (x,y) 必须相同。为了更详细地说明这一点,假设 (x,y) 是坐标,z 是温度。
  • 不确定如何精确,但是如何匹配列表中的项目,如果 x,y 相等,将该元素附加到新列表中,然后您将平均第三个位置跨度>
  • 我试过了,但我正在处理大型列表,并希望避免创建更多列表:)

标签: python list average defaultdict


【解决方案1】:

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

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

【讨论】:

  • 我得到 [[1, 2, 16], [3, 4, 5], [6, 7, 9]]。知道为什么我得到整数吗?我正在使用 Python 2.7.3。好的,如果都是整数,它会返回整数。没关系。
  • @CosmoSurreal 对于 python 2.x,您需要将其转换为浮点数。喜欢float(len(x))
【解决方案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)]

【讨论】:

  • 谢谢你。我还没有习惯 defaultdict 可以实现什么,这让我大开眼界。
猜你喜欢
  • 1970-01-01
  • 2015-05-17
  • 1970-01-01
  • 2012-02-20
  • 2017-08-13
  • 2021-01-12
  • 1970-01-01
相关资源
最近更新 更多