2015-11-13 564 views
3

我正在分析一些非常密切地聚類的數字時間度量。我想獲得平均值,標準偏差等。一些輸入很大,所以我認爲我可以避免創建數百萬個數字的列表,而不是使用Python集合.Counter對象作爲緊湊的表示形式。計算python集合中的值的平均值。計算器

實施例:我的小輸入之一產生一個collection.Counter[(48, 4082), (49, 1146)]這意味着4082個出現的值48和1146個出現的值49對於這個數據組我手動計算平均數爲類似48.2192042846的。

當然,如果我有一個簡單的4,082 + 1,146 = 5,228整數列表,我只是將它提供給numpy.mean()。

我的問題:如何計算collections.Counter對象中的值的描述性統計量,就像我有一個數字列表一樣?我必須創建完整列表還是有快捷方式?

+0

(沒有時間寫回答​​自己,但'np.average'有一個權重參數,你可以做手工STDDEV,請參閱[這裏](http://stackoverflow.com/questions/2413522/weighted - 標準偏差 - 在-numpy的) - 如果有人想用這種方法,我會刪除此) – DSM

回答

3

雖然你可以卸載製作值的列表後,一切numpy,這將是慢於需要。相反,您可以使用您需要的實際定義。

平均是他們的計數將所有的數字簡單相加,所以這是非常簡單的:

sum_of_numbers = sum(number*count for number, count in counter) 
count = sum(count for n, count in counter) 
mean = sum_of_numbers/count 

標準差是更復雜一點。這是方差的平方根,進而方差被定義爲「平方的平均值減去平均值的平方」爲您收集。 Soooo ...

total_squares = sum(number*number * count for number, count in counter) 
mean_of_squares = total_squares/count 
variance = mean_of_squares - mean * mean 
std_dev = math.sqrt(variance) 

一點點手動工作,但也應該快得多,如果數字集有很多重複。

+0

爲了簡潔起見,請使用這個。感謝@Martijn Pieters澄清Python的整數和浮點數學特性,請不要生氣,我接受這個答案:) – chrisinmtown

5

collections.Counter()dict的一個子類。只需使用Counter().values()得到計數的列表:

counts = Counter(some_iterable_to_be_counted) 
mean = numpy.mean(counts.values()) 

請注意,我沒有呼叫Counter.most_common()這裏,這將產生你在你的問題發佈(key, count)元組列表。

如果必須使用的Counter.most_common()輸出就可以過濾掉只是一個列表理解的計數:

mean = numpy.mean([count for key, count in most_common_list]) 

如果您正在使用Python 3(dict.values()返回一個字典視圖),您既可以通在list(counts.values())中,或使用標準庫staticstics.mean() function,這需要一個可迭代的(包括dict.values()字典視圖)。

如果您打算計算其平均值鍵值按其計數加權,您可以直接從計數器值進行自己的計算。在Python 2這會是:

from __future__ import division 

mean = sum(key * count for key, count in counter.iteritems())/sum(counter.itervalues()) 

from __future__進口應該在你的模塊的頂部,並確保您不會遇到大的浮點數溢出的問題。在Python 3中,將被簡化爲:

mean = sum(key * count for key, count in counter.items())/sum(counter.values()) 

中位數可以用平分計算;按鍵對(key, count)對進行排序,對計數求和,並將中途點對分爲計數的累加和。插入點的索引指向已排序鍵列表中的中鍵。

+0

感謝我的固定標記寫了一個答案。我不想要計數的意思,我希望數值的均值適合計數。我編輯帖子以添加手動計算的平均值,值約爲48.2。 – chrisinmtown

+0

@chrislott:那麼你的選擇是自己計算平均值:Python 2的'sum(key * count for key,count in counter.iteritems())/ sum(counter.itervalues(),0.0)'。 –

+0

Yes still使用Python 2,但我不懂Python的數字能力,你是說我不必關心給定鍵的值很大無聲溢出,算什麼? – chrisinmtown

0

除非你想編寫你自己的統計函數,否則不存在prêt-à-porter解決方案(據我所知)。

所以最後你需要創建列表,最快的方法是使用numpy。一種方法是:

import numpy as np 

# One memory allocation will be considerably faster 
# if you have multiple discrete values. 
elements = np.ones(48+49) 
elements[0:48] *= 4082 
elements[48:] *= 1146 

# Then you can use numpy statistical functions to calculate 
np.mean(elements) 
np.std(elements) 
# ... 

更新:從現有集合中創建元素。計數器()對象

c = collections.Counter({48: 4082, 49: 1146}) 
elements = np.ones(sum(c.values())) 
idx = 0 
for value, occurrences in c.iteritems(): 
    elements[idx:idx + occurrences] *= value 
    idx += occurrences