寻找列表的众数

154

给定一个项目列表,回想一下,列表的众数是出现最频繁的项目。

我想知道如何创建一个函数,可以找到列表的众数,但如果列表没有众数(例如,列表中的所有项目仅出现一次),则显示消息。我想自己从头开始制作这个函数,而不引入任何函数。


抱歉,您能解释一下“列表模式”具体是什么意思吗? - Vikas
8
“众数”是一组数据中出现次数最多的元素(如果有的话)。有些定义将其扩展为计算所有这样的元素的算术平均值,如果有多个众数的话。 - Jeremy Roman
1
这里有很多错误的答案! 例如assert(mode[1, 1, 1]) == Noneassert(mode[1, 2, 3, 4]) == None。一个数字要成为“众数”,它必须在列表中出现的次数比至少另一个数字多,并且它不能是列表中唯一的数字。 - lifebalance
27个回答

2

一个数字要成为众数,它必须在列表中出现的次数比至少另一个数字要多,并且它不能是列表中唯一的数字。因此,我重构了@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 

2
我的大脑决定从零开始完全重新设计。高效而简洁 :) (开个玩笑lol)
import random

def removeDuplicates(arr):
    dupFlag = False

    for i in range(len(arr)):
        #check if we found a dup, if so, stop
        if dupFlag:
            break

        for j in range(len(arr)):
            if ((arr[i] == arr[j]) and (i != j)):
                arr.remove(arr[j])
                dupFlag = True
                break;

    #if there was a duplicate repeat the process, this is so we can account for the changing length of the arr
    if (dupFlag):
        removeDuplicates(arr)
    else:
        #if no duplicates return the arr
        return arr

#currently returns modes and all there occurences... Need to handle dupes
def mode(arr):
    numCounts = []

    #init numCounts
    for i in range(len(arr)):
        numCounts += [0]

    for i in range(len(arr)):
        count = 1
        for j in range(len(arr)):
            if (arr[i] == arr[j] and i != j):
                count += 1
        #add the count for that number to the corresponding index
        numCounts[i] = count

    #find which has the greatest number of occurences
    greatestNum = 0
    for i in range(len(numCounts)):
        if (numCounts[i] > greatestNum):
            greatestNum = numCounts[i]

    #finally return the mode(s)
    modes = []
    for i in range(len(numCounts)):
        if numCounts[i] == greatestNum:
            modes += [arr[i]]
    
    #remove duplicates (using aliasing)
    print("modes: ", modes)
    removeDuplicates(modes)
    print("modes after removing duplicates: ", modes)
    
    return modes


def initArr(n):
    arr = []
    for i in range(n):
        arr += [random.randrange(0, n)]
    return arr

#initialize an array of random ints
arr = initArr(1000)
print(arr)
print("_______________________________________________")

modes = mode(arr)

#print result
print("Mode is: ", modes) if (len(modes) == 1) else print("Modes are: ", modes)

2

这里是如何找到列表的平均值、中位数和众数:

最初的回答:

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

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 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
如果两个项目具有相同数量的出现次数,则此方法将失败。 - akshaynagpal

2

以下是无需使用任何导入功能的查找列表众数的简单代码:

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)

如果存在多个模式,则应返回最小节点。

1

对于那些寻求最小模式的人,例如双峰分布的情况,可以使用numpy。

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

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
这将返回所有模式:
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

好的! 社区已经有很多答案,其中一些使用了另一个函数,而你不想要它。
让我们创建一个非常简单且易于理解的函数。

import numpy as np

#Declare Function Name
def calculate_mode(lst):

下一步是查找列表中的唯一元素及其相应的频率
unique_elements,freq = np.unique(lst, return_counts=True)

获取模式
max_freq = np.max(freq)   #maximum frequency
mode_index = np.where(freq==max_freq)  #max freq index
mode = unique_elements[mode_index]   #get mode by index
return mode

Example

lst =np.array([1,1,2,3,4,4,4,5,6])
print(calculate_mode(lst))
>>> Output [4]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接