2012-05-29 71 views
61

給定項目列表,請回想一下列表中的模式是最經常出現的項目。查找列表模式

我想知道如何創建一個函數,可以找到列表的模式,但如果列表中沒有模式(例如,列表中的所有項目只出現一次)顯示一條消息。我想在不導入任何功能的情況下做出這個功能。我試圖從頭開始創建自己的功能。

+0

很抱歉,但你能解釋一下你的「的模式意味着什麼清單「? – Vikas

+3

@Vikas:模式是最常出現的元素(如果有的話)。如果有多個定義,則有些定義將其擴展爲取所有這些元素的算術平均值。 –

+0

這裏有很多錯誤的答案!例如'assert(mode [1,1,1])== None'和 'assert(mode [1,2,3,4])== None'。對於一個數字來說,它是一個「模式」,它必須比列表中的至少一個其他數字出現更多次數,並且它不能是列表中唯一的數字。 – lifebalance

回答

73

您可以使用在collections包裏面有一個mode -esque功能

from collections import Counter 
data = Counter(your_list_in_here) 
data.most_common() # Returns all unique items and their counts 
data.most_common(1) # Returns the highest occurring item 

筆記提供的Counter:計數器是在Python 2.7新,是不是在早期版本。

+12

這個問題指出用戶想要從頭開始創建一個功能 - 即沒有導入。 – dbliss

+1

您的最後一行返回一個列表,其中包含一個包含模式及其頻率的元組。爲了得到一個模式,使用'Counter(your_list_in_here).most_common(1)[0] [0]'。如果有多個模式,則返回任意一個模式。 –

+0

假設有'n'最常見的'模式'。如果Counter(your_list_in_here).most_common(1)[0] [0]讓你成爲第一個模式,你會如何獲得另一個最常見的'mode'?只需用'1'替換最後一個'0'?人們可以根據自己的喜好定製'模式'。 – mikey

19

從某些統計軟件(即SciPyMATLAB)中抽取一個,它們只返回最小的最常用值,因此如果兩個值的出現次數相同,則返回最小值。希望一個例子將有所幫助:

>>> from scipy.stats import mode 

>>> mode([1, 2, 3, 4, 5]) 
(array([ 1.]), array([ 1.])) 

>>> mode([1, 2, 2, 3, 3, 4, 5]) 
(array([ 2.]), array([ 2.])) 

>>> mode([1, 2, 2, -3, -3, 4, 5]) 
(array([-3.]), array([ 2.])) 

你有什麼理由不遵循這個約定嗎?

+2

爲什麼只有最小模式纔會返回? – zyxue

0

爲什麼不

def print_mode (thelist): 
    counts = {} 
    for item in thelist: 
    counts [item] = counts.get (item, 0) + 1 
    maxcount = 0 
    maxitem = None 
    for k, v in counts.items(): 
    if v > maxcount: 
     maxitem = k 
     maxcount = v 
    if maxcount == 1: 
    print "All values only appear once" 
    elif counts.values().count (maxcount) > 1: 
    print "List has multiple modes" 
    else: 
    print "Mode of list:", maxitem 

這並不一定,它應該有一些錯誤檢查,但它會發現模式沒有導入任何功能,如果所有值只出現一次將打印的消息。它還會檢測到共享相同最大數量的多個項目,但尚不清楚您是否想要這樣。

+0

所以即時通訊嘗試做的是檢測多個項目顯示相同的計數,然後顯示所有項目相同的計數 – bluelantern

+0

你有沒有親自嘗試過嗎?從我的代碼擴展到使它打印具有相同計數的所有項目相當簡單。 – lxop

1

我寫了這個方便的功能來找到模式。

def mode(nums): 
    corresponding={} 
    occurances=[] 
    for i in nums: 
      count = nums.count(i) 
      corresponding.update({i:count}) 

    for i in corresponding: 
      freq=corresponding[i] 
      occurances.append(freq) 

    maxFreq=max(occurances) 

    keys=corresponding.keys() 
    values=corresponding.values() 

    index_v = values.index(maxFreq) 
    global mode 
    mode = keys[index_v] 
    return mode 
+1

如果2個項目具有相同的編號,則此方法將失敗。的發生。 – akshaynagpal

27

的Python 3.4包括方法statistics.mode,所以它很簡單:

>>> from statistics import mode 
>>> mode([1, 1, 2, 3, 3, 3, 3, 4]) 
3 

你可以有任何類型的元素在列表中,而不僅僅是數字:

>>> mode(["red", "blue", "blue", "red", "green", "red", "red"]) 
'red' 
+8

在使用模式([1,1,1,2,3,3,3,3,4])時引發錯誤,其中1和3重複相同的時間。理想情況下,應該返回最大但相同次數的最小值。 StatisticsError:無唯一模式;找到2個同樣常見的值 –

+1

沒有使用這個3.4統計包,但是scipy.stats.mode會返回最小值,在這種情況下是1.然而,我會在某些情況下更喜歡拋出錯誤... – wordsmith

1

短,但不知何故醜:

def mode(arr) : 
    m = max([arr.count(a) for a in arr]) 
    return [x for x in arr if arr.count(x) == m][0] if m>1 else None 

使用字典,略少醜:

def mode(arr) : 
    f = {} 
    for a in arr : f[a] = f.get(a,0)+1 
    m = max(f.values()) 
    t = [(x,f[x]) for x in f if f[x]==m] 
    return m > 1 t[0][0] else None 
0
def mode(inp_list): 
    sort_list = sorted(inp_list) 
    dict1 = {} 
    for i in sort_list:   
      count = sort_list.count(i) 
      if i not in dict1.keys(): 
       dict1[i] = count 

    maximum = 0 #no. of occurences 
    max_key = -1 #element having the most occurences 

    for key in dict1: 
     if(dict1[key]>maximum): 
      maximum = dict1[key] 
      max_key = key 
     elif(dict1[key]==maximum): 
      if(key<max_key): 
       maximum = dict1[key] 
       max_key = key 

    return max_key 
1

該函數返回模式或功能的模式不管有多少,以及在數據集中的一個或多個模式的頻率。如果沒有模式(即所有項目只出現一次),該函數返回一個錯誤字符串。這與上面的A_nagpal函數類似,但在我看來,它更完整,我認爲對於任何Python新手(比如真正的)來說,閱讀這個問題是很容易理解的。

def l_mode(list_in): 
    count_dict = {} 
    for e in (list_in): 
     count = list_in.count(e) 
     if e not in count_dict.keys(): 
      count_dict[e] = count 
    max_count = 0 
    for key in count_dict: 
     if count_dict[key] >= max_count: 
      max_count = count_dict[key] 
    corr_keys = [] 
    for corr_key, count_value in count_dict.items(): 
     if count_dict[corr_key] == max_count: 
      corr_keys.append(corr_key) 
    if max_count == 1 and len(count_dict) != 1: 
     return 'There is no mode for this data set. All values occur only once.' 
    else: 
     corr_keys = sorted(corr_keys) 
     return corr_keys, max_count 
+0

I說這只是因爲你說「該函數返回一個錯誤字符串。」讀取'return'的行沒有這個數據集的模式。所有的值只出現一次。''可以變成一個錯誤信息'traceback'作爲if條件:*下一行indent *提高ValueError('這個數據集沒有模式,所有的值只出現一次。 )[這是一個列表](https://docs.python.org/3/tutorial/errors.html),您可以提出不同類型的錯誤。 – mikey

77

您可以使用max函數和一個鍵。看看python max function using 'key' and lambda expression

max(set(list), key=list.count) 
+5

這是OP的正確答案,因爲它不需要任何額外的進口。好工作,大衛 –

+5

在我看來,這將運行在'O(n ** 2)'。可以? – lirtosiast

+4

這有二次方運行時 –

0
def mode(data): 
    lst =[] 
    hgh=0 
    for i in range(len(data)): 
     lst.append(data.count(data[i])) 
    m= max(lst) 
    ml = [x for x in data if data.count(x)==m ] #to find most frequent values 
    mode = [] 
    for x in ml: #to remove duplicates of mode 
     if x not in mode: 
     mode.append(x) 
    return mode 
print mode([1,2,2,2,2,7,7,5,5,5,5]) 
15

有很多簡單的方法可以找到一個列表的Python中的模式,例如:

import statistics 
statistics.mode([1,2,3,3]) 
>>> 3 

或者,你可以通過它的計數發現最大

max(array, key = array.count) 

這兩種方法的問題是它們不適用於多種模式。第一個返回錯誤,第二個返回第一個模式。

爲了找到一組的模式,你可以使用此功能:

def mode(array): 
    most = max(list(map(array.count, array))) 
    return list(set(filter(lambda x: array.count(x) == most, array))) 
+0

使用這個模式,當有兩個元素出現相同的時間時會給出錯誤。 – user31688

2

長一點,但可以有多種模式,並能得到字符串最計數或數據類型的混合。

def getmode(inplist): 
    '''with list of items as input, returns mode 
    ''' 
    dictofcounts = {} 
    listofcounts = [] 
    for i in inplist: 
     countofi = inplist.count(i) # count items for each item in list 
     listofcounts.append(countofi) # add counts to list 
     dictofcounts[i]=countofi # add counts and item in dict to get later 
    maxcount = max(listofcounts) # get max count of items 
    if maxcount ==1: 
     print "There is no mode for this dataset, values occur only once" 
    else: 
     modelist = [] # if more than one mode, add to list to print out 
     for key, item in dictofcounts.iteritems(): 
      if item ==maxcount: # get item from original list with most counts 
       modelist.append(str(key)) 
     print "The mode(s) are:",' and '.join(modelist) 
     return modelist 
0

這是一個簡單的函數,它獲取列表中出現的第一個模式。它使用列表元素作爲關鍵字和出現次數的字典,然後讀取字典值以獲取模式。

def findMode(readList): 
    numCount={} 
    highestNum=0 
    for i in readList: 
     if i in numCount.keys(): numCount[i] += 1 
     else: numCount[i] = 1 
    for i in numCount.keys(): 
     if numCount[i] > highestNum: 
      highestNum=numCount[i] 
      mode=i 
    if highestNum != 1: print(mode) 
    elif highestNum == 1: print("All elements of list appear once.") 
1

如果你有興趣或者最小,最大或所有模式:

def get_small_mode(numbers, out_mode): 
    counts = {k:numbers.count(k) for k in set(numbers)} 
    modes = sorted(dict(filter(lambda x: x[1] == max(counts.values()), counts.items())).keys()) 
    if out_mode=='smallest': 
     return modes[0] 
    elif out_mode=='largest': 
     return modes[-1] 
    else: 
     return modes 
0

這將返回所有模式:

def mode(numbers) 
    largestCount = 0 
    modes = [] 
    for x in numbers: 
     if x in modes: 
      continue 
     count = numbers.count(x) 
     if count > largestCount: 
      del modes[:] 
      modes.append(x) 
      largestCount = count 
     elif count == largestCount: 
      modes.append(x) 
    return modes 
0

如果你想有一個明確的方法,有用對於課堂,只能通過理解使用列表和詞典,你可以這樣做:

def mode(my_list): 
    # Form a new list with the unique elements 
    unique_list = sorted(list(set(my_list))) 
    # Create a comprehensive dictionary with the uniques and their count 
    appearance = {a:my_list.count(a) for a in unique_list} 
    # Calculate max number of appearances 
    max_app = max(appearance.values()) 
    # Return the elements of the dictionary that appear that # of times 
    return {k: v for k, v in appearance.items() if v == max_app} 
0

對於一個數字爲mode,它必須出現的次數多於,列表中至少有一個其他數字,它必須是而不是是列表中唯一的數字。所以,我重構@ mathwizurd的回答(用difference法)如下:

def mode(array): 
    ''' 
    returns a set containing valid modes 
    returns a message if no valid mode exists 
     - when all numbers occur the same number of times 
     - when only one number occurs in the list 
     - when no number occurs in the list 
    ''' 
    most = max(map(array.count, array)) if array else None 
    mset = set(filter(lambda x: array.count(x) == most, array)) 
    return mset if set(array) - mset else "list does not have a mode!" 

這些測試順利通過:

mode([]) == None 
mode([1]) == None 
mode([1, 1]) == None 
mode([1, 1, 2, 2]) == None