2010-10-09 48 views
4

我試圖找到從字典中提取平均值的最快/最有效的方法。我正在處理的任務要求它執行數千次,因此每次只需遍歷字典中的所有值以查找平均值就完全沒有效率。數百和數百個新的鍵值對被添加到字典中,我們需要在每次發生這種情況時找到平均值。我們還需要在每次發生數千次的值更新時找到新的平均值。Python - 每次修改整個字典時找到平均值的最快方法?

在此先感謝 - 這是一個很棒的地方。

回答

11

創建您自己的字典類,用於跟蹤數和總,然後可以快速返回平均:

class AvgDict(dict): 
    def __init__(self): 
     self._total = 0.0 
     self._count = 0 

    def __setitem__(self, k, v): 
     if k in self: 
      self._total -= self[k] 
      self._count -= 1 
     dict.__setitem__(self, k, v) 
     self._total += v 
     self._count += 1 

    def __delitem__(self, k): 
     v = self[k] 
     dict.__delitem__(self, k) 
     self._total -= v 
     self._count -= 1 

    def average(self): 
     if self._count: 
      return self._total/self._count 

a = AvgDict() 
assert a.average() is None 
a[1] = 1 
assert a.average() == 1 
a[2] = 10 
assert a.average() == 5.5 
assert a[2] == 10 
a[1] = 5 
assert a.average() == 7.5 
del a[1] 
assert a.average() == 10 
+0

難道你需要重寫'__delitem__'嗎? – Ponkadoodle 2010-10-09 17:29:43

+0

也許不是,因爲我實際上並沒有刪除任何值 - 只是更新它們。 – Georgina 2010-10-09 17:38:50

+0

哎呀,我忽略了'__delitem__',爲了完整性我會加上它。 – 2010-10-09 18:01:29

1

繼承自dict並計算每次調用__setitem__時的平均值。

既然您可以在您的詞典課程中存儲以前的平均值,並且只對其平均值和添加的新值進行平均,那應該相當快 - 第一次添加新項目時,平均值就是這個值。

2

是基於運行平均值以下,所以如果你知道以前的平均水平:

At = (A0 * N + E)/(N + 1) 

At is the average after addition of the new element 
A0 is the average before addition of the new element 
N is the number of element before addition of the new element 
E is the new element's value 

其簡單的哥哥工作,如果你保持元素的總和的標籤:

At = (T + E)/(N + 1) 

T is the total of all elements 
A0 is the average before addition of the new element 
N is the number of element before addition of the new element 
E is the new element's value 

當一個值被刪除,你可以做類似的事情:

At = (A0 * N - E)/(N - 1) 

而且當一個值更新:

At = (A0 * N - E0 + E1)/(N) 

E0 is value before updating, E1 is value after updating. 
相關問題