2012-10-16 19 views
1

我會用一個例子來說明我的問題:的Python:尋找相同的列表出現的次數和平均

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,如果按[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做到這一點?有任何想法嗎?

+0

如果什麼x和z是相同的,但y是不同的? –

+0

不,只有(x,y)必須相同。爲了給這個更多的上下文,我們假設(x,y)是座標,z是溫度。 – CosmoSurreal

+1

不知道具體如何,但匹配列表中的項目又如何,如果x,y相等,則將該元素附加到一個新列表中,然後您將平均排列第三個位置 – chimpsarehungry

回答

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

我越來越[[1,2,16],[3,4,5],[6,7,9]]。任何想法,爲什麼我得到整數?我正在使用Python 2.7.3。好吧,如果所有都是整數,它會返回整數。沒關係。 – CosmoSurreal

+0

@CosmoSurreal對於Python 2.x,您需要將其轉換爲float。像'float(len(x))' – JBernardo

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

謝謝你。我還沒有習慣默認設置可以實現的功能,這讓人大開眼界。 – CosmoSurreal