web-dev-qa-db-fra.com

Trouver le mode d'une liste

Etant donné une liste d’éléments, rappelons que le mode de la liste est l’élément le plus fréquent.

Je voudrais savoir comment créer une fonction qui peut trouver le mode d’une liste mais qui affiche un message si la liste n’a pas de mode (par exemple, tous les éléments de la liste apparaissent une seule fois). Je veux faire cette fonction sans importer aucune fonction. J'essaie de créer ma propre fonction à partir de zéro.

88
bluelantern

Vous pouvez utiliser la fonction max et une clé. Regardez la fonction python max en utilisant 'key' et l'expression lambda .

max(set(list), key=list.count)
113
David Dao

Vous pouvez utiliser le Counter fourni dans le collections package qui a une fonction 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

Remarque: Le compteur est nouveau dans Python 2.7 et n'est pas disponible dans les versions antérieures.

86
Christian Witts

Python 3.4 inclut la méthode statistics.mode , elle est donc simple:

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

Vous pouvez avoir n'importe quel type d'éléments dans la liste, pas seulement numérique:

>>> mode(["red", "blue", "blue", "red", "green", "red", "red"])
 'red'
46
jabaldonedo

Il existe de nombreuses façons simples de trouver le mode d’une liste en Python, par exemple:

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

Ou, vous pouvez trouver le max par son nombre

max(array, key = array.count)

Le problème avec ces deux méthodes est qu'elles ne fonctionnent pas avec plusieurs modes. Le premier renvoie une erreur, tandis que le second renvoie le premier mode. 

Pour trouver les modes d'un ensemble, vous pouvez utiliser cette fonction:

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

En reprenant certains logiciels de statistiques, à savoir SciPy et MATLAB , ceux-ci renvoient simplement la valeur la plus petite et la plus commune. Ainsi, si deux valeurs apparaissent régulièrement, les plus petites sont renvoyées. Espérons qu'un exemple aidera:

>>> 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.]))

Y a-t-il une raison pour laquelle vous ne pouvez pas suivre cette convention?

21
Chris

Si vous êtes intéressé par le plus petit, le plus grand ou tous les modes:

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
3
tashuhka

Un peu plus long, mais peut avoir plusieurs modes et obtenir une chaîne avec la plupart des comptes ou une combinaison de types de données. 

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 
2
timpjohns

Étendre la réponse de la communauté qui ne fonctionnera pas quand la liste sera vide, voici le code de travail pour le mode

def mode(arr):
        if arr==[]:
            return None
        else:
            return max(set(arr), key=arr.count)
2
Kardi Teknomo

J'ai écrit cette fonction pratique pour trouver le mode. 

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
2
user2975335

Bref, mais en quelque sorte moche:

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

En utilisant un dictionnaire, un peu moins moche:

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
2
Carl

Pourquoi pas juste

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

Cela ne nécessite pas quelques vérifications d'erreur, mais il trouvera le mode sans importer de fonctions et imprimera un message si toutes les valeurs apparaissent une seule fois. Il détectera également plusieurs éléments partageant le même nombre maximum, bien que ce ne soit pas clair si vous le vouliez. 

1
lxop

Cette fonction renvoie le ou les modes d'une fonction, peu importe le nombre, ainsi que la fréquence du ou des modes de l'ensemble de données. S'il n'y a pas de mode (c'est-à-dire que tous les éléments n'apparaissent qu'une fois), la fonction renvoie une chaîne d'erreur. Ceci est similaire à la fonction de A_nagpal ci-dessus mais est, à mon humble avis, plus complet, et je pense que c'est plus facile à comprendre pour tout novice Python (comme le vôtre) qui lit cette question pour comprendre.

 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
1
user4406935

Voici comment trouver la moyenne, la médiane et le mode d’une liste:

import numpy as np
from scipy import stats

#to take input
size = int(input())
numbers = list(map(int, input().split()))

print(np.mean(numbers))
print(np.median(numbers))
print(int(stats.mode(numbers)[0]))
1
pankaj

Cela retournera tous les modes:

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
Tim Orton

Voici une fonction simple qui obtient le premier mode qui se produit dans une liste. Il crée un dictionnaire avec les éléments de la liste sous forme de clés et le nombre d’occurrences, puis lit les valeurs dict pour obtenir le mode.

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.")
0
SMS von der Tann
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
0
akshaynagpal
#function to find mode
def mode(data):  
    modecnt=0
#for count of number appearing
    for i in range(len(data)):
        icount=data.count(data[i])
#for storing count of each number in list will be stored
        if icount>modecnt:
#the loop activates if current count if greater than the previous count 
            mode=data[i]
#here the mode of number is stored 
            modecnt=icount
#count of the appearance of number is stored
    return mode
print mode(data1)
0
Rinki Nag

Si vous voulez une approche claire, utile pour la classe et utilisant uniquement des listes et des dictionnaires par compréhension, vous pouvez faire:

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

Pour qu'un nombre soit une mode, il doit apparaître plus de fois que au moins un autre nombre dans la liste, et il doit être non le seul nombre de la liste. Donc, j'ai refactored la réponse de @ mathwizurd (pour utiliser la méthode difference ) comme suit: 

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!" 

Ces tests réussissent: 

mode([]) == None 
mode([1]) == None
mode([1, 1]) == None 
mode([1, 1, 2, 2]) == None 
0
lifebalance
import numpy as np
def get_mode(xs):
    values, counts = np.unique(xs, return_counts=True)
    max_count_index = np.argmax(counts) #return the index with max value counts
    return values[max_count_index]
print(get_mode([1,7,2,5,3,3,8,3,2]))
0
sim
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])
0