Finden des Modus einer Liste

126

Denken Sie bei einer Liste von Elementen daran, dass der Modus der Liste das Element ist, das am häufigsten auftritt.

Ich möchte wissen, wie man eine Funktion erstellt, die den Modus einer Liste findet, aber eine Meldung anzeigt, wenn die Liste keinen Modus hat (z. B. werden alle Elemente in der Liste nur einmal angezeigt). Ich möchte diese Funktion erstellen, ohne Funktionen zu importieren. Ich versuche, meine eigene Funktion von Grund auf neu zu erstellen.

bluelantern
quelle
Entschuldigung, aber können Sie erklären, was genau Sie unter "Modus der Liste" verstehen?
Vikas
5
@Vikas: Der Modus ist das am häufigsten vorkommende Element (falls vorhanden). Einige Definitionen erweitern es, um das arithmetische Mittel aller dieser Elemente zu verwenden, wenn es mehr als eines gibt.
Jeremy Roman
So viele falsche Antworten hier! Zum Beispiel assert(mode[1, 1, 1]) == Noneund assert(mode[1, 2, 3, 4]) == None. Damit eine Zahl eine ist mode, muss sie öfter vorkommen als mindestens eine andere Zahl in der Liste, und sie darf nicht die einzige Zahl in der Liste sein.
Lebensbalance

Antworten:

156

Sie können die maxFunktion und eine Taste verwenden. Schauen Sie sich die Python Max-Funktion mit 'key' und Lambda-Ausdruck an .

max(set(lst), key=lst.count)
David Dao
quelle
6
Dies ist die richtige Antwort auf OP, da keine zusätzlichen Importe erforderlich sind. Gute Arbeit, David
Jason Parham
12
Es scheint mir, dass dies einlaufen würde O(n**2). Macht es?
Lirtosiast
7
Dies hat quadratische Laufzeit
Padraic Cunningham
20
Könnte auch nur verwenden max(lst, key=lst.count). (Und ich würde wirklich keine Liste nennen list.)
Stefan Pochmann
2
Kann jemand erklären, wie dies für bimodale Verteilungen funktioniert? zB a = [22, 33, 11, 22, 11]; print(max(set(a), key=a.count))kehrt zurück 11. Wird immer der Minimalmodus zurückgegeben? Und wenn ja, warum?
Battey
99

Sie können das Counterim collectionsPaket enthaltene verwenden, das eine mode-esque-Funktion hat

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

Hinweis: Counter ist neu in Python 2.7 und in früheren Versionen nicht verfügbar.

Christian Witts
quelle
19
Die Frage besagt, dass der Benutzer eine Funktion von Grund auf neu erstellen möchte - dh keine Importe.
dbliss
3
Ihre letzte Zeile gibt eine Liste zurück, die ein Tupel enthält, das einen Modus und seine Häufigkeit enthält. Um nur einen Modus zu erhalten, verwenden Sie Counter(your_list_in_here).most_common(1)[0][0]. Wenn es mehr als einen Modus gibt, wird ein beliebiger zurückgegeben.
Rory Daulton
1
Angenommen, es gibt nam häufigsten modes. Wenn Counter (your_list_in_here) .most_common (1) [0] [0] Ihnen den ersten Modus bietet, wie würden Sie einen anderen am häufigsten verwendeten erhalten mode? Ersetzen Sie einfach den letzten 0durch 1? Man kann eine Funktion machen, um die modenach ihren Wünschen anzupassen ..
1
Wie kann ich die größte dieser Zahlen zurückgeben, wenn es mehr als einen Modus gibt?
Akin Hwan
59

Python 3.4 enthält die Methode statistics.mode, daher ist es einfach:

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

Sie können jede Art von Elementen in der Liste haben, nicht nur numerische:

>>> mode(["red", "blue", "blue", "red", "green", "red", "red"])
 'red'
jabaldonedo
quelle
17
Wirft einen Fehler bei der Verwendung des Modus ([1, 1,1,1, 2, 3, 3, 3, 3, 4]), wobei 1 und 3 gleich oft wiederholt werden. Idealerweise sollte die kleinste der Zahlen zurückgegeben werden, die am größten, aber gleich oft ist. StatisticsError: kein eindeutiger Modus; fand 2 gleich häufige Werte
aman_novice
4
Ich habe dieses 3.4-Statistikpaket nicht verwendet, aber scipy.stats.mode gibt das kleinste zurück, in diesem Fall 1. Ich würde jedoch in bestimmten Fällen den Fehlerauswurf bevorzugen ...
wordsmith
2
@aman_novice, das Problem wurde in Python 3.8 behoben. docs.python.org/3/library/statistics.html#statistics.mode
Michael D
2
Es wurde auch Python 3.8 hinzugefügt multimode, das mehrere Modi zurückgibt, wenn es mehr als einen gibt.
Stason
30

Ein Blatt von einer Statistiksoftware nehmen, nämlich SciPy und MATLAB , geben diese nur den kleinsten häufigsten Wert zurück. Wenn also zwei Werte gleich häufig auftreten, werden die kleinsten davon zurückgegeben. Hoffentlich hilft ein Beispiel:

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

Gibt es einen Grund, warum Sie dieser Konvention nicht folgen können?

Chris
quelle
4
Warum wird nur der kleinste Modus zurückgegeben, wenn mehrere vorhanden sind?
Zyxue
@zyxue einfache statistische Konvention
chrisfs
2
@chrisfs und damit es den größten Modus zurückgibt, wenn es mehrere gibt?
Akin Hwan
25

Es gibt viele einfache Möglichkeiten, den Modus einer Liste in Python zu finden, z.

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

Oder Sie können das Maximum anhand seiner Anzahl ermitteln

max(array, key = array.count)

Das Problem bei diesen beiden Methoden ist, dass sie nicht mit mehreren Modi funktionieren. Der erste gibt einen Fehler zurück, während der zweite den ersten Modus zurückgibt.

Um die Modi eines Sets zu finden, können Sie folgende Funktion verwenden:

def mode(array):
    most = max(list(map(array.count, array)))
    return list(set(filter(lambda x: array.count(x) == most, array)))
mathwizurd
quelle
3
Wenn Sie den Modus verwenden, tritt ein Fehler auf, wenn zwei Elemente in der gleichen Zeit auftreten.
Abhishek Mishra
Entschuldigung, habe diesen Kommentar sehr spät gesehen. Statistics.mode (Array) würde einen Fehler mit mehreren Modi zurückgeben, aber keine der anderen Methoden.
Mathwizurd
8

Wenn Sie die Community-Antwort erweitern, die nicht funktioniert, wenn die Liste leer ist, finden Sie hier den Arbeitscode für den Modus:

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

Falls Sie an den kleinsten, größten oder allen Modi interessiert sind:

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
Taschuhka
quelle
2

Ich habe diese praktische Funktion geschrieben, um den Modus zu finden.

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
user2975335
quelle
2
Diese Methode schlägt fehl, wenn 2 Elemente dieselbe Nummer haben. von Vorkommen.
Akshaynagpal
2

Kurz, aber irgendwie hässlich:

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

Mit einem Wörterbuch etwas weniger hässlich:

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

Etwas länger, kann jedoch mehrere Modi haben und Zeichenfolgen mit den meisten Zählungen oder einer Mischung von Datentypen erhalten.

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 
Pauken
quelle
2

Damit eine Zahl eine ist mode, muss sie öfter vorkommen als mindestens eine andere Zahl in der Liste, und sie darf nicht die einzige Zahl in der Liste sein. Also habe ich die Antwort von @ mathwizurd (um die differenceMethode zu verwenden) wie folgt überarbeitet :

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

Diese Tests bestehen erfolgreich:

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

Warum nicht einfach

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

Dies hat nicht einige Fehlerprüfungen, die es haben sollte, aber es findet den Modus ohne Importieren von Funktionen und druckt eine Nachricht, wenn alle Werte nur einmal angezeigt werden. Es werden auch mehrere Elemente erkannt, die dieselbe maximale Anzahl haben, obwohl nicht klar war, ob Sie dies wollten.

lxop
quelle
Ich
Haben Sie das tatsächlich selbst versucht? Die Erweiterung meines Codes hier, damit alle Elemente mit der gleichen Anzahl gedruckt werden, ist ziemlich einfach.
lxop
1

Diese Funktion gibt den Modus oder die Modi einer Funktion zurück, egal wie viele, sowie die Häufigkeit des Modus oder der Modi im Datensatz. Wenn es keinen Modus gibt (dh alle Elemente treten nur einmal auf), gibt die Funktion eine Fehlerzeichenfolge zurück. Dies ähnelt der obigen Funktion von A_nagpal, ist jedoch meiner bescheidenen Meinung nach vollständiger, und ich denke, es ist für alle Python-Neulinge (wie Ihre wirklich), die diese Frage lesen, einfacher zu verstehen.

 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
user4406935
quelle
Ich sage dies nur, weil Sie gesagt haben "Die Funktion gibt eine Fehlerzeichenfolge zurück." Die gelesene Zeile return 'There is no mode for this data set. All values occur only once.'kann in eine Fehlermeldung umgewandelt werden , die lautet traceback: "if-Bedingung: Nächste Zeile mit Einzug erhöht ValueError (" Für diesen Datensatz gibt es keinen Modus. Alle Werte treten nur einmal auf. ") Hier ist eine Liste verschiedener Arten von Fehler, die Sie auslösen können.
1

Dies gibt alle Modi zurück:

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

Einfacher Code, der den Modus der Liste ohne Importe findet:

nums = #your_list_goes_here
nums.sort()
counts = dict()
for i in nums:
    counts[i] = counts.get(i, 0) + 1
mode = max(counts, key=counts.get)

Bei mehreren Modi sollte der minimale Knoten zurückgegeben werden.

baby_yoda
quelle
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
akshaynagpal
quelle
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])
Venkata Prasanth T.
quelle
0

Hier ist eine einfache Funktion, die den ersten Modus abruft, der in einer Liste auftritt. Es erstellt ein Wörterbuch mit den Listenelementen als Schlüssel und Anzahl der Vorkommen und liest dann die Diktatwerte, um den Modus zu erhalten.

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.")
SMS von der Tann
quelle
0

Wenn Sie einen klaren Ansatz wünschen, der für den Unterricht nützlich ist und nur Listen und Wörterbücher nach Verständnis verwendet, können Sie Folgendes tun:

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}
Maria Frances Gaska
quelle
0
#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)

quelle
Sie sollten Ihre Antwort mit Kommentaren oder weiteren Details erklären
Michael
0

So finden Sie Mittelwert, Median und Modus einer 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]))
pankaj
quelle
0
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]))
sim
quelle
0

Für diejenigen, die nach dem Minimalmodus suchen, z. B.: Fall einer bimodalen Verteilung mit numpy.

import numpy as np
mode = np.argmax(np.bincount(your_list))
V3K3R
quelle
0

Der Modus eines Datensatzes ist / sind die Mitglieder , die am häufigsten im Satz vorkommen. Wenn zwei Mitglieder am häufigsten mit der gleichen Häufigkeit angezeigt werden, haben die Daten zwei Modi. Das nennt man bimodal .

Wenn es mehr als zwei Modi gibt, werden die Daten als multimodal bezeichnet . Wenn alle Mitglieder im Datensatz gleich oft angezeigt werden, hat der Datensatz überhaupt keinen Modus .

Die folgende Funktion modes()kann verwendet werden, um Modi in einer bestimmten Datenliste zu finden :

import numpy as np; import pandas as pd

def modes(arr):
    df = pd.DataFrame(arr, columns=['Values'])
    dat = pd.crosstab(df['Values'], columns=['Freq'])
    if len(np.unique((dat['Freq']))) > 1:
        mode = list(dat.index[np.array(dat['Freq'] == max(dat['Freq']))])
        return mode
    else:
        print("There is NO mode in the data set")

Ausgabe:

# For a list of numbers in x as
In [1]: x = [2, 3, 4, 5, 7, 9, 8, 12, 2, 1, 1, 1, 3, 3, 2, 6, 12, 3, 7, 8, 9, 7, 12, 10, 10, 11, 12, 2]
In [2]: modes(x)
Out[2]: [2, 3, 12]
# For a list of repeated numbers in y as
In [3]: y = [2, 2, 3, 3, 4, 4, 10, 10]
In [4]: modes(y)
There is NO mode in the data set
# For a list of stings/characters in z as
In [5]: z = ['a', 'b', 'b', 'b', 'e', 'e', 'e', 'd', 'g', 'g', 'c', 'g', 'g', 'a', 'a', 'c', 'a']
In [6]: modes(z)
Out[6]: ['a', 'g']

Wenn wir keine Funktion aus diesen Paketen importieren numpyoder pandasaufrufen möchten, kann die Funktion wie folgt geschrieben werden, um dieselbe Ausgabe zu erhalten modes():

def modes(arr):
    cnt = []
    for i in arr:
        cnt.append(arr.count(i))
    uniq_cnt = []
    for i in cnt:
        if i not in uniq_cnt:
            uniq_cnt.append(i)
    if len(uniq_cnt) > 1:
        m = []
        for i in list(range(len(cnt))):
            if cnt[i] == max(uniq_cnt):
                m.append(arr[i])
        mode = []
        for i in m:
            if i not in mode:
                mode.append(i)
        return mode
    else:
        print("There is NO mode in the data set")
shubh
quelle