การค้นหาโหมดของรายการ


126

เมื่อระบุรายการโปรดจำไว้ว่าไฟล์ โหมดของรายการเป็นรายการที่เกิดขึ้นบ่อยที่สุด

ฉันต้องการทราบวิธีสร้างฟังก์ชันที่สามารถค้นหาโหมดของรายการ แต่จะแสดงข้อความหากรายการไม่มีโหมด (เช่นรายการทั้งหมดในรายการจะปรากฏเพียงครั้งเดียว) ฉันต้องการสร้างฟังก์ชันนี้โดยไม่ต้องนำเข้าฟังก์ชันใด ๆ ฉันพยายามสร้างฟังก์ชันของตัวเองตั้งแต่เริ่มต้น


ขออภัยคุณสามารถอธิบายความหมายของ "โหมดรายการ" ได้หรือไม่
Vikas

5
@Vikas: โหมดนี้เป็นองค์ประกอบที่เกิดขึ้นบ่อยที่สุด (ถ้ามี) คำจำกัดความบางคำขยายให้ใช้ค่าเฉลี่ยเลขคณิตขององค์ประกอบดังกล่าวทั้งหมดหากมีมากกว่าหนึ่ง
Jeremy Roman

ตอบผิดมากมายที่นี่! สำหรับเช่นassert(mode[1, 1, 1]) == Noneและ assert(mode[1, 2, 3, 4]) == None. สำหรับตัวเลขที่จะเป็น a modeจะต้องเกิดขึ้นหลายครั้งมากกว่าตัวเลขอื่นอย่างน้อยหนึ่งตัวในรายการและต้องไม่ใช่ตัวเลขเดียวในรายการ
lifebalance

คำตอบ:


156

คุณสามารถใช้maxฟังก์ชันและปุ่ม มีลักษณะที่หลามฟังก์ชั่นการใช้สูงสุด 'key' และการแสดงออกแลมบ์ดา

max(set(lst), key=lst.count)

6
นี่คือคำตอบที่ถูกต้องสำหรับ OP โดยพิจารณาว่าไม่ต้องการการนำเข้าเพิ่มเติมใด ๆ ทำได้ดีมาก David
Jason Parham

12
สำหรับฉันแล้วสิ่งนี้จะวิ่งเข้าO(n**2)มา ทำมัน?
lirtosiast

7
สิ่งนี้มีรันไทม์กำลังสอง
Padraic Cunningham

20
max(lst, key=lst.count)นอกจากนี้ยังสามารถใช้เพียง (และฉันจะไม่เรียกรายชื่อlistจริงๆ)
Stefan Pochmann

2
ใครช่วยอธิบายวิธีการทำงานของการแจกแจงแบบไบโมดอลได้บ้าง เช่นผลตอบแทนa = [22, 33, 11, 22, 11]; print(max(set(a), key=a.count)) 11มันจะกลับสู่โหมดต่ำสุดเสมอหรือไม่? และถ้าเป็นเช่นนั้นทำไม?
Battey

99

คุณสามารถใช้สิ่งที่Counterให้มาในcollectionsแพ็คเกจซึ่งมีmodeฟังก์ชันa -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 และไม่มีในเวอร์ชันก่อนหน้า


19
คำถามระบุว่าผู้ใช้ต้องการสร้างฟังก์ชันตั้งแต่เริ่มต้นนั่นคือไม่มีการนำเข้า
dbliss

3
บรรทัดสุดท้ายของคุณจะแสดงรายการที่มีทูเปิลที่มีโหมดและความถี่ Counter(your_list_in_here).most_common(1)[0][0]เพื่อให้ได้เป็นเพียงแค่การใช้งานโหมด หากมีมากกว่าหนึ่งโหมดระบบจะส่งกลับโหมดใดโหมดหนึ่งโดยพลการ
Rory Daulton

1
สมมติว่ามีที่พบมากที่สุดn modesถ้า Counter (your_list_in_here) .most_common (1) [0] [0] ทำให้คุณได้รับโหมดแรกคุณจะได้โหมดอื่นที่พบบ่อยที่สุดmodeอย่างไร? เพียงแค่แทนที่สุดท้าย0ด้วย1? หนึ่งสามารถทำฟังก์ชั่นปรับแต่งตามความmodeต้องการได้ ..

1
หากมีมากกว่าหนึ่งโหมดฉันจะคืนค่าที่ใหญ่ที่สุดของตัวเลขเหล่านี้ได้อย่างไร
Akin Hwan

59

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'

17
แสดงข้อผิดพลาดในการใช้โหมด ([1, 1,1,1, 2, 3, 3, 3, 3, 4]) โดยที่ 1 และ 3 ทำซ้ำตามจำนวนครั้งที่เท่ากัน ตามหลักการแล้วควรส่งคืนค่าที่น้อยที่สุดของจำนวนที่มากที่สุด แต่จำนวนครั้งเท่ากัน StatisticsError: ไม่มีโหมดเฉพาะ พบ 2 ค่าที่เท่ากัน
aman_novice

4
ยังไม่ได้ใช้แพ็คเกจสถิติ 3.4 นี้ แต่ scipy.stats.mode จะส่งคืนค่าที่เล็กที่สุดในกรณีนี้ 1 อย่างไรก็ตามฉันชอบโยนข้อผิดพลาดในบางกรณี ...
wordmith

2
@aman_novice ปัญหาได้รับการแก้ไขแล้วใน Python 3.8 docs.python.org/3/library/statistics.html#statistics.mode
Michael D

2
นอกจากนี้ยังเพิ่ม python 3.8 multimodeซึ่งส่งคืนหลายโหมดเมื่อมีมากกว่าหนึ่ง
stason

30

การนำใบไม้จากซอฟต์แวร์สถิติบางตัว ได้แก่SciPyและMATLABสิ่งเหล่านี้จะส่งคืนค่าที่พบบ่อยที่สุดดังนั้นหากค่าสองค่าเกิดขึ้นบ่อยเท่ากันค่าที่น้อยที่สุดจะถูกส่งกลับ หวังว่าตัวอย่างจะช่วยได้:

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

มีเหตุผลใดบ้างที่คุณไม่สามารถปฏิบัติตามอนุสัญญานี้?


4
เหตุใดจึงส่งคืนเฉพาะโหมดที่เล็กที่สุดเมื่อมีหลายโหมด
zyxue

@zyxue การประชุมทางสถิติอย่างง่าย
chrisfs

2
@chrisfs และเพื่อให้มันกลับสู่โหมดที่ใหญ่ที่สุดหากมีหลาย ๆ ?
Akin Hwan

25

มีหลายวิธีง่ายๆในการค้นหาโหมดของรายการใน 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)))

3
การใช้โหมดนี้ทำให้เกิดข้อผิดพลาดเมื่อมีสององค์ประกอบเกิดขึ้นในระยะเวลาเท่ากัน
Abhishek Mishra

ขออภัยเห็นความคิดเห็นนี้ล่าช้าจริงๆ Statistics.mode (อาร์เรย์) จะส่งคืนข้อผิดพลาดที่มีหลายโหมด แต่ไม่มีวิธีใดทำ
mathwizurd

7

การขยายคำตอบของชุมชนที่จะไม่ทำงานเมื่อรายการว่างเปล่านี่คือรหัสการทำงานสำหรับโหมด:

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

3

ในกรณีที่คุณสนใจโหมดเล็กที่สุดใหญ่ที่สุดหรือทั้งหมด:

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

2

ฉันเขียนฟังก์ชันที่มีประโยชน์นี้เพื่อค้นหาโหมด

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
วิธีนี้จะล้มเหลวหาก 2 รายการมีหมายเลขเดียวกัน ของการเกิดขึ้น
akshaynagpal

2

สั้น แต่น่าเกลียด:

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

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 

2

สำหรับตัวเลขที่จะเป็น a modeต้องเกิดขึ้นหลายครั้งมากกว่าตัวเลขอื่นอย่างน้อยหนึ่งตัวในรายการและต้องไม่ใช่ตัวเลขเดียวในรายการ ดังนั้นฉันจึง refactored คำตอบของ @ 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 

1

ทำไมไม่เพียง

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

สิ่งนี้ไม่มีการตรวจสอบข้อผิดพลาดเล็กน้อยที่ควรมี แต่จะพบโหมดโดยไม่ต้องนำเข้าฟังก์ชันใด ๆ และจะพิมพ์ข้อความหากค่าทั้งหมดปรากฏเพียงครั้งเดียว นอกจากนี้ยังตรวจพบหลายรายการที่มีจำนวนสูงสุดเท่ากันแม้ว่าจะไม่ชัดเจนว่าคุณต้องการก็ตาม


ดังนั้นสิ่งที่ฉันพยายามทำคือตรวจจับหลายรายการที่แสดงจำนวนเท่ากันแล้วแสดงรายการทั้งหมดด้วยจำนวนเท่ากัน
bluelantern

คุณได้ลองทำด้วยตัวเองแล้วหรือยัง? ส่วนขยายจากรหัสของฉันที่นี่เพื่อให้พิมพ์รายการทั้งหมดที่มีจำนวนเท่ากันนั้นค่อนข้างตรงไปตรงมา
lxop

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

ฉันพูดแบบนี้เพราะคุณพูดว่า "ฟังก์ชันส่งคืนสตริงข้อผิดพลาด" บรรทัดที่อ่านreturn 'There is no mode for this data set. All values occur only once.'สามารถเปลี่ยนเป็นข้อความแสดงข้อผิดพลาดโดยมีtracebackas if condition: next line with indent Raise ValueError ('ไม่มีโหมดสำหรับชุดข้อมูลนี้ค่าทั้งหมดเกิดขึ้นเพียงครั้งเดียว') นี่คือรายการประเภทต่างๆของ ข้อผิดพลาดที่คุณสามารถเพิ่มได้

1

สิ่งนี้จะส่งคืนทุกโหมด:

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

1

โค้ดง่ายๆที่ค้นหาโหมดของรายการโดยไม่ต้องนำเข้าใด ๆ :

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)

ในกรณีที่มีหลายโหมดควรส่งคืนโหนดขั้นต่ำ


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

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

0

นี่คือฟังก์ชันง่ายๆที่รับโหมดแรกที่เกิดขึ้นในรายการ มันทำให้พจนานุกรมที่มีองค์ประกอบรายการเป็นคีย์และจำนวนครั้งที่เกิดขึ้นจากนั้นอ่านค่า dict เพื่อรับโหมด

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

หากคุณต้องการแนวทางที่ชัดเจนเป็นประโยชน์สำหรับห้องเรียนและใช้เฉพาะรายการและพจนานุกรมตามความเข้าใจคุณสามารถทำได้:

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

คุณควรอธิบายคำตอบของคุณพร้อมความคิดเห็นหรือรายละเอียดเพิ่มเติม
Michael

0

นี่คือวิธีที่คุณสามารถค้นหาค่าเฉลี่ยค่ามัธยฐานและโหมดของรายการ:

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

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

0

สำหรับผู้ที่มองหาโหมดขั้นต่ำเช่นกรณีของการแจกแจงแบบไบ - โมดอลโดยใช้ numpy

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

0

โหมดของชุดข้อมูลคือ / เป็นสมาชิกที่เกิดขึ้นบ่อยที่สุดในชุดข้อมูล หากมีสมาชิกสองคนที่ปรากฏบ่อยที่สุดโดยมีจำนวนครั้งเท่ากันข้อมูลนั้นจะมีสองโหมด นี้เรียกว่า bimodal bimodal

ถ้ามีมากกว่า 2 โหมดแล้วข้อมูลจะถูกเรียกว่าต่อเนื่อง หากสมาชิกทั้งหมดในชุดข้อมูลปรากฏในจำนวนครั้งเท่ากันแสดงว่าชุดข้อมูลนั้นไม่มีโหมดเลย

ฟังก์ชันต่อไปนี้modes()สามารถทำงานเพื่อค้นหาโหมดในรายการข้อมูลที่กำหนด:

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

เอาท์พุท:

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

หากเราไม่ต้องการนำเข้าnumpyหรือpandasเรียกใช้ฟังก์ชันใด ๆ จากแพ็คเกจเหล่านี้ดังนั้นเพื่อให้ได้ผลลัพธ์เดียวกันนี้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")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.