Menemukan mode daftar

126

Diberikan daftar item, ingat bahwa mode daftar adalah item yang paling sering muncul.

Saya ingin mengetahui cara membuat fungsi yang dapat menemukan mode daftar tetapi yang menampilkan pesan jika daftar tidak memiliki mode (mis., Semua item dalam daftar hanya muncul sekali). Saya ingin membuat fungsi ini tanpa mengimpor fungsi apa pun. Saya mencoba membuat fungsi saya sendiri dari awal.

bluelantern
sumber
Maaf, tapi bisakah Anda menjelaskan apa yang Anda maksud dengan 'mode daftar'?
Vikas
5
@Vikas: mode adalah elemen yang paling sering muncul (jika ada). Beberapa definisi memperluasnya untuk mengambil mean aritmatika dari semua elemen jika ada lebih dari satu.
Jeremy Roman
Banyak sekali jawaban yang salah disini! Untuk misalnya assert(mode[1, 1, 1]) == Nonedan assert(mode[1, 2, 3, 4]) == None. Agar angka menjadi a mode, angka itu harus muncul lebih sering daripada setidaknya satu angka lain dalam daftar, dan itu tidak boleh menjadi satu-satunya angka dalam daftar.
keseimbangan hidup

Jawaban:

156

Anda dapat menggunakan maxfungsi dan kunci. Lihat fungsi python max menggunakan 'key' dan ekspresi lambda .

max(set(lst), key=lst.count)
David Dao
sumber
6
Ini jawaban yang benar untuk OP, mengingat tidak memerlukan impor tambahan. Kerja bagus, David
Jason Parham
12
Menurut saya ini akan berjalan masuk O(n**2). Melakukannya?
lirtosiast
7
Ini memiliki runtime kuadrat
Padraic Cunningham
20
Bisa juga pakai saja max(lst, key=lst.count). (Dan saya benar-benar tidak akan meminta daftar list.)
Stefan Pochmann
2
Adakah yang bisa menjelaskan bagaimana ini bekerja untuk distribusi bi-modal? misalnya a = [22, 33, 11, 22, 11]; print(max(set(a), key=a.count))kembali 11. Apakah akan selalu mengembalikan mode minimum? Dan jika ya, mengapa?
Pertempuran
99

Anda dapat menggunakan yang Counterdisediakan dalam collectionspaket yang memiliki modefungsi -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

Catatan: Penghitung baru di python 2.7 dan tidak tersedia di versi sebelumnya.

Christian Witts
sumber
19
Pertanyaan tersebut menyatakan bahwa pengguna ingin membuat fungsi dari awal - yaitu, tidak ada impor.
dbliss
3
Baris terakhir Anda mengembalikan daftar yang berisi tupel yang berisi mode dan frekuensinya. Untuk mendapatkan hanya penggunaan mode Counter(your_list_in_here).most_common(1)[0][0]. Jika ada lebih dari satu mode, ini mengembalikan mode arbitrer.
Rory Daulton
1
Misalkan ada yang npaling umum modes. Jika Counter (your_list_in_here) .most_common (1) [0] [0] memberi Anda mode pertama, bagaimana Anda mendapatkan mode lain yang paling umum mode? Ganti saja yang terakhir 0dengan 1? Seseorang dapat membuat fungsi untuk menyesuaikan modedengan keinginan mereka ..
1
jika ada lebih dari satu mode, bagaimana cara mengembalikan angka terbesar?
Akin Hwan
59

Python 3.4 menyertakan metode ini statistics.mode, jadi langsung saja:

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

Anda dapat memiliki semua jenis elemen dalam daftar, tidak hanya numerik:

>>> mode(["red", "blue", "blue", "red", "green", "red", "red"])
 'red'
jabaldonedo
sumber
17
Melempar kesalahan saat menggunakan mode ([1, 1,1,1, 2, 3, 3, 3, 3, 4]) di mana 1 dan 3 mengulangi jumlah waktu yang sama. Idealnya, harus mengembalikan angka terkecil yang terbesar tetapi sama banyaknya. StatisticsError: tidak ada mode unik; menemukan 2 nilai yang sama-sama umum
aman_novice
4
Belum menggunakan paket statistik 3.4 ini, tetapi scipy.stats.mode akan mengembalikan yang terkecil, dalam kasus ini 1. Namun, saya lebih suka membuang kesalahan dalam kasus tertentu ...
wordsmith
2
@aman_novice, masalah ini diselesaikan dengan Python 3.8. docs.python.org/3/library/statistics.html#statistics.mode
Michael D
2
python 3.8 juga ditambahkan multimode, yang mengembalikan banyak mode bila ada lebih dari satu.
stason
30

Mengambil daun dari beberapa perangkat lunak statistik, yaitu SciPy dan MATLAB , ini hanya mengembalikan nilai paling umum terkecil, jadi jika dua nilai muncul sama seringnya, nilai terkecil dikembalikan. Semoga sebuah contoh akan membantu:

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

Adakah alasan mengapa Anda tidak bisa mengikuti konvensi ini?

Chris
sumber
4
Mengapa hanya mode terkecil yang dikembalikan jika ada beberapa?
zyxue
@zyxue konvensi statistik sederhana
chrisfs
2
@chrisfs dan membuatnya mengembalikan mode terbesar jika ada beberapa?
Akin Hwan
25

Ada banyak cara sederhana untuk menemukan mode list dengan Python seperti:

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

Atau, Anda dapat menemukan maks dengan hitungannya

max(array, key = array.count)

Masalah dengan kedua metode tersebut adalah mereka tidak bekerja dengan banyak mode. Yang pertama mengembalikan kesalahan, sedangkan yang kedua mengembalikan mode pertama.

Untuk menemukan mode set, Anda dapat menggunakan fungsi ini:

def mode(array):
    most = max(list(map(array.count, array)))
    return list(set(filter(lambda x: array.count(x) == most, array)))
mathwizurd
sumber
3
Menggunakan mode, memberikan kesalahan ketika ada dua elemen terjadi dalam waktu yang sama.
Abhishek Mishra
Maaf, terlambat melihat komentar ini. Statistics.mode (array) akan mengembalikan kesalahan dengan beberapa mode, tetapi tidak ada metode lain yang melakukannya.
mathwizurd
7

Memperluas jawaban Komunitas yang tidak akan berfungsi ketika daftar kosong, berikut adalah kode kerja untuk mode:

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

Jika Anda tertarik dengan mode terkecil, terbesar, atau semua:

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
tashuhka
sumber
2

Saya menulis fungsi praktis ini untuk menemukan 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
pengguna2975335
sumber
2
Metode ini akan gagal jika 2 item memiliki no yang sama. dari kejadian.
akshaynagpal
2

Pendek, tapi jelek:

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

Menggunakan kamus, sedikit tidak jelek:

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

Sedikit lebih lama, tetapi bisa memiliki beberapa mode dan bisa mendapatkan string dengan jumlah atau campuran tipe data terbanyak.

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

Agar bilangan menjadi a mode, itu harus muncul lebih sering daripada setidaknya satu nomor lain dalam daftar, dan itu tidak boleh menjadi satu-satunya nomor dalam daftar. Jadi, saya refactored jawaban @ mathwizurd (untuk menggunakan differencemetode) sebagai berikut:

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

Tes ini berhasil lulus:

mode([]) == None 
mode([1]) == None
mode([1, 1]) == None 
mode([1, 1, 2, 2]) == None 
keseimbangan hidup
sumber
1

Kenapa tidak adil

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

Ini tidak memiliki beberapa pemeriksaan kesalahan yang seharusnya, tetapi itu akan menemukan mode tanpa mengimpor fungsi apa pun dan akan mencetak pesan jika semua nilai muncul hanya sekali. Ini juga akan mendeteksi beberapa item yang berbagi jumlah maksimum yang sama, meskipun tidak jelas apakah Anda menginginkannya.

lxop
sumber
Jadi apa yang saya coba lakukan adalah mendeteksi beberapa item yang menampilkan hitungan yang sama dan kemudian menampilkan semua item dengan jumlah yang sama
bluelantern
Apakah Anda benar-benar mencobanya sendiri? Perpanjangan dari kode saya di sini agar mencetak semua item dengan jumlah yang sama cukup mudah.
lxop
1

Fungsi ini mengembalikan mode atau mode dari suatu fungsi berapa pun jumlahnya, serta frekuensi mode atau mode dalam kumpulan data. Jika tidak ada mode (mis. Semua item terjadi hanya sekali), fungsi mengembalikan string kesalahan. Ini mirip dengan fungsi A_nagpal di atas tetapi, menurut pendapat saya, lebih lengkap, dan menurut saya lebih mudah dipahami untuk pemula Python mana pun (seperti Anda benar-benar) membaca pertanyaan ini untuk memahami.

 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
pengguna4406935
sumber
Saya mengatakan ini hanya karena Anda mengatakan "fungsi mengembalikan string kesalahan." Baris yang berbunyi return 'There is no mode for this data set. All values occur only once.'dapat diubah menjadi pesan kesalahan dengan traceback`` if condition: next line with indent raise ValueError ('Tidak ada mode untuk kumpulan data ini. Semua nilai terjadi hanya sekali.') Berikut adalah daftar berbagai jenis kesalahan yang bisa Anda tingkatkan.
1

Ini akan mengembalikan semua mode:

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

Kode sederhana yang menemukan mode daftar tanpa impor apa pun:

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)

Dalam kasus beberapa mode, itu harus mengembalikan node minimum.

baby_yoda
sumber
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
sumber
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
sumber
0

Berikut adalah fungsi sederhana yang mendapatkan mode pertama yang muncul dalam daftar. Itu membuat kamus dengan elemen daftar sebagai kunci dan jumlah kejadian dan kemudian membaca nilai dict untuk mendapatkan 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.")
SMS von der Tann
sumber
0

Jika Anda menginginkan pendekatan yang jelas, berguna untuk kelas dan hanya menggunakan daftar dan kamus dengan pemahaman, Anda dapat melakukan:

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}
María Frances Gaska
sumber
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)

sumber
Anda harus menjelaskan jawaban Anda dengan komentar atau detail lebih lanjut
Michael
0

Berikut adalah bagaimana Anda dapat menemukan mean, median dan mode dari sebuah daftar:

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
sumber
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
sumber
0

Untuk yang mencari mode minimum, misal: kasus distribusi bi-modal, menggunakan numpy.

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

Mode suatu kumpulan data adalah anggota yang paling sering muncul dalam kumpulan tersebut. Jika ada dua anggota yang paling sering muncul dengan frekuensi yang sama, maka data memiliki dua mode. Ini disebut bimodal .

Jika ada lebih dari 2 mode, maka datanya disebut multimodal . Jika semua anggota dalam kumpulan data muncul dalam jumlah yang sama, maka kumpulan data tersebut tidak memiliki mode sama sekali.

Fungsi berikut modes()dapat bekerja untuk menemukan mode dalam daftar data yang diberikan:

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

Keluaran:

# 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']

Jika kita tidak ingin mengimpor numpyatau pandasmemanggil fungsi apa pun dari paket-paket ini, maka untuk mendapatkan keluaran yang sama ini, modes()fungsi dapat ditulis sebagai:

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
sumber