2012-03-05 58 views
4

我試圖計算值的Python中的列表模式(最頻繁的值)。我想出了一個解決方案,無論如何都給出了錯誤的答案,但我後來意識到我的數據可能是多變的;計算模式在多模式列表在Python

ie 1,1,2,3,4,4 mode = 1 & 4 

這裏是我想出迄今:

def mode(valueList): 
    frequencies = {} 
    for value in valueList: 
    if value in frequencies: 
     frequencies[value] += 1 
    else: 
     frequencies[value] = 1 
    mode = max(frequencies.itervalues()) 
    return mode 

我覺得這裏的問題是,我輸出值,而不是最大值的指針。無論如何,任何人都可以提出一個更好的方法來做到這一點,可以在多種模式下工作嗎?或者失敗了,我如何解決目前爲止所發現的問題並確定單一模式?

正如你可能會說我很新的蟒蛇,感謝您的幫助。

編輯:應該提到我在Python 2.4

+0

你真的應該升級到Python的支持的最新版本。 – 2012-07-22 09:08:18

回答

5

好了,第一個問題是肯定的,你在回國的frequences值,而不是重點。這意味着你獲得了模式的,而不是模式本身。通常情況下,要獲得模式,你會使用key關鍵字參數爲最大,像這樣:

>>> max(frequencies, key=counts.get()) 

但在2.4不存在!以下是我認爲將在2.4工作的方法:

>>> import random 
>>> l = [random.randrange(0, 5) for _ in range(50)] 
>>> frequencies = {} 
>>> for i in l: 
...  frequencies[i] = frequencies.get(i, 0) + 1 
... 
>>> frequencies 
{0: 11, 1: 13, 2: 8, 3: 8, 4: 10} 
>>> mode = max((v, k) for k, v in frequencies.iteritems())[1] 
>>> mode 
1 
>>> max_freq = max(frequencies.itervalues()) 
>>> modes = [k for k, v in frequencies.iteritems() if v == max_freq] 
>>> modes 
[1] 

我喜歡的裝飾 - 排序 - 去除裝飾成語的cmp關鍵字。我認爲它更具可讀性。可能是那只是我。

+0

非常感謝,我也應該提到我在2.4。我已更新該帖子。 – Captastic 2012-03-05 13:57:00

+0

@Captastic,argh。沒有'defaultdict',沒有'Counter',沒有'key'參數到'max'。唷。必須以艱苦的方式做到這一點...只需一秒。 – senderle 2012-03-05 14:04:24

+0

在Py2.4中,你可以用'cmp'作爲'max'而不是'key'(它現在還不存在)。所以,'mode = max(頻率,cmp = lambda i,j:cmp(counts [i],counts [j]))''。 – lvc 2012-03-05 14:05:54

5

在Python> = 2.7,頻率表使用collections.Counter。它檢查一對(_, f)是否具有相同的頻率作爲最頻繁的元件

from collections import Counter 
from itertools import takewhile 

data = [1,1,2,3,4,4] 
freq = Counter(data) 
mostfreq = freq.most_common() 
modes = list(takewhile(lambda x_f: x_f[1] == mostfreq[0][1], mostfreq)) 

注意使用匿名函數(lambda)的。

+0

對不起,應該提到我在2.4,謝謝。 – Captastic 2012-03-05 13:57:49

+2

@Captastic:那你真的應該升級。 Python 2.4是從2004年開始的;即使Python 2.5不再接收安全補丁。 – 2012-03-05 14:20:24

+0

我會該死如果我能得到去年「takewhile」行沒有一個SyntaxError工作在我的3.2.3版本,但我是一個新手。思考? – 2012-09-18 17:43:03

1

您可以使用計數器的TOP值,而迭代,這樣的事情:

def mode(valueList): 
    frequencies = {} 
    mx = None 
    for value in valueList: 
    if value in frequencies: 
     frequencies[value] += 1 
    else: 
     frequencies[value] = 1 
    if not mx or frequencies[value] > mx[1]: 
     mx = (value, frequencies[value]) 

    mode = mx[0] 
    return mode 

用於多種模式的另一種方法,使用nlargest,它可以給你一本字典的N個最大值:

from heapq import nlargest 
import operator 

def mode(valueList, nmodes): 
    frequencies = {} 

    for value in valueList: 
    frequencies[value] = frequencies.get(value, 0) + 1 

    return [x[0] for x in nlargest(nmodes,frequencies.iteritems(),operator.itemgetter(1))] 
+0

這樣做,謝謝。雖然不知道如何將其轉換爲多種模式。 – Captastic 2012-03-05 14:00:13

+0

看到我的編輯上面一個更動態的方法 – 2012-03-05 14:06:28

+0

感謝您的輸入,我已經與senderles的做法,但我會如果只是爲了學習經驗,以有您這樣的發揮。 – Captastic 2012-03-05 14:24:56