2013-04-20 61 views
0

我生產從3個值之差的平均值,並希望把它放在一個列表檢查,如果值已經在列表中

列表中的示例中,我想平均看起來像這樣:

... 
[6.0, 270.0, -55.845848680633168], 
[6.0, 315.0, -47.572000492889323], 
[6.5, 0.0, -47.806802767243724], 
[6.5, 45.0, -48.511643275159528], 
[6.5, 90.0, -45.002053150122123], 
[6.5, 135.0, -51.034656702050455], 
[6.5, 180.0, -53.266356523649002], 
[6.5, 225.0, -47.872632929518339], 
[6.5, 270.0, -52.09662072002746], 
[6.5, 315.0, -48.563996448937075]] 

前兩列匹配時會有多達3行(這兩列是極座標),當這種情況下,我想取第三個元素之間的差異,求平均值並追加極性點的座標和平均結果放入新列表中

for a in avg_data: 
    comparison = [] 
    for b in avg_data: 
     if a[0] == b[0] and a[1] == b[1]: 
      comparison.append(b[2]) 

    print comparison  
    z = 0 # reset z to 0, z does not need set now in if len(comp) == 1 

    if len(comparison) == 2: # if there are only 2 elements, compare them 
     z += -(comparison[0]) + comparison[1] 
    if len(comparison) == 3: # if all 3 elements are there, compare all 3 
     z += -(comparison[0]) + comparison[1] 
     z += -(comparison[0]) + comparison[2] 
     z += -(comparison[1]) + comparison[2] 
     z = z/3 #average the variation 

    avg_variation.append([a[0], a[1], z]) #append the polar coordinates and the averaged variation to a list 

此代碼將正確的數據輸出到列表中,除了每次遇到匹配的極座標時輸出該數據,因此最終會出現重複的行。

要停止這個我試過執行if語句來尋找執行平均再

if a[0] not in avg_variation and a[1] not in avg_variation: 

這不起作用之前在avg_variation名單極座標匹配,我得到的錯誤

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

我不認爲任何或全部是我正在尋找的,因爲我只想檢查前兩列而不是第三列對已經附加的值。任何人有任何想法我怎麼能使我的陳述更好?

要清理多一點我的實際問題是什麼:

我的代碼通過對列表嵌套的列表,其中1號2個單元匹配搜索,執行3號元素的計算,然後將它們附加到一個新的列表。我的問題是,如果有2或3行的前2個元素相匹配,它將結果附加到新列表中2或3次,我希望它只做一次

編輯:對不起,我最初的問題是misleadng關於我的代碼的目的。

+0

所以,只是爲了得到它直,你得到的名單都應該在他們的第三個數量方面相同的值(這應該是你的第三列的平均值以上)? – arshajii 2013-04-20 17:36:55

+0

結果列表應該有嵌套列表,其第一個和第二個元素是極座標,第三個元素是這些極座標值的平均值。在結果列表中,每行應該有唯一的極座標。 – 2013-04-20 17:49:52

+0

@markmcmurray:你的代碼並不計算這些值的平均值,但它會計算出不同元素之間的平均(有符號)差異。 – DSM 2013-04-20 17:52:00

回答

3

IIUC,我認爲一個簡單的方法是像

import numpy as np 
from itertools import combinations 
from collections import defaultdict 

def average_difference(seq): 
    return np.mean([j-i for i,j in combinations(seq, 2)]) if len(seq) > 1 else 0 

def average_over_xy(seq, fn_to_apply): 
    d = defaultdict(list) 
    for x,y,z in seq: 
     d[x,y].append(z) 

    outlist = [[x,y,fn_to_apply(z)] for (x,y),z in sorted(d.items())] 
    return outlist 

它遍歷所有行,使一本字典,其中x,y座標是鍵和元素的值列表,然後將該字典轉換爲列表的排序列表,在z中的元素中應用指定的功能。例如,我們可以在代碼中使用的平均簽約,並下令區別,如:

產生

>>> seq = [[1, 2, 30], [1, 2, 40], [1, 2, 50], [1, 3, 4], [1, 3, 6], [2, 10, 5]] 
>>> average_over_xy(seq, average_difference) 
[[1, 2, 13.333333333333334], [1, 3, 2.0], [2, 10, 0]] 

請注意,這我上面匹配,答案您已經定義的方式,取決於元素的順序,即

>>> average_over_xy([[1,2,3],[1,2,4]], average_difference) 
[[1, 2, 1.0]] 
>>> average_over_xy([[1,2,4],[1,2,3]], average_difference) 
[[1, 2, -1.0]] 

如果你願意,你可以使用

def average_difference_sorted(seq): 
    return average_difference(sorted(seq)) 

代替或使用標準偏差或任何你喜歡的。 (你沒有提到你的用例,所以我會假設你已經按照你想要的順序得到了這個列表,你知道這個缺陷,而你真的需要average_difference)。

基於numpy的一些技巧我們可以做到,並且有一些推廣的方法,但是使用defaultdict來累積值是一個方便的模式,它通常足夠快。

+0

這工作,謝謝。對不起,以一種令人困惑的方式來說明問題。 – 2013-04-20 18:14:02

0

你還沒有給出所有必要的信息來確定這一點,但我相信你的錯誤是由對numpy數組執行邏輯操作引起的。請參閱this answer以解決類似錯誤的問題。

沒有更多的信息,很難複製問題的上下文來嘗試它,但可能在if語句的布爾操作中更具體。

1

這裏是一個可能的解決方案:

l=[[6.0, 270.0, -55.845848680633168], 
[6.0, 315.0, -47.572000492889323], 
[6.5, 0.0, -47.806802767243724], 
[6.0, 180.0, -53.266356523649002], 
[6.0, 225.0, -47.872632929518339], 
[6.0, 270.0, -52.09662072002746], 
[6.0, 315.0, -48.563996448937075]] 

# First, we change the structure so that the pair of coordinates 
# becomes a tuple which can be used as dictionary key 
l=[[(c1, c2), val] for c1, c2, val in l] 

# We build a dictionary coord:[...list of values...] 
d={} 
for coord, val in l: 
    d.setdefault(coord,[]).append(val) 

# Here, I compute the mean of each list of values. 
# Apply your own function ! 

means = [[coord[0], coord[1], sum(vals)/len(vals)] for coord, vals in d.items()] 

print means 
相關問題