查找列表的模式

给定一个项目列表,记住列表的 模式是最常出现的项目。

我想知道如何创建一个函数,可以找到一个列表的模式,但显示一条消息,如果列表没有一个模式(例如,所有的项目在列表中只出现一次)。我想在不导入任何函数的情况下创建这个函数。我试着从零开始创造我自己的功能。

346413 次浏览

您可以使用 collections包中提供的 Counter,它具有 mode样式的功能

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中是新的,在早期版本中不可用。

借鉴一些统计软件,即 SciPyMATLAB,它们只返回最小的最常见值,因此如果两个值同样频繁出现,则返回其中最小的值。希望一个例子能有所帮助:

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

你有什么理由不能遵守这个惯例吗?

为什么不呢

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

它没有进行一些应该进行的错误检查,但是它会在不导入任何函数的情况下找到模式,并且在所有值只出现一次的情况下打印一条消息。它还将检测多个项目共享相同的最大计数,虽然它不清楚如果你想这样做。

我写了这个方便的函数来查找模式。

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

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'

很短,但有点丑:

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

此函数返回函数的模式或模式,无论其数量多少,以及数据集中的模式或模式的频率。如果没有模式(即。所有项只出现一次) ,函数返回一个错误字符串。这类似于上面的 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

您可以使用 max函数和一个键。

max(set(lst), key=lst.count)
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])

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

时间稍长,但可以有多种模式,并且可以获得具有大多数计数或混合数据类型的字符串。

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

下面是一个简单的函数,它获取列表中出现的第一个模式。它使用列表元素作为键和出现次数创建一个 dictionary,然后读取 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.")

如果你对最小的、最大的或者所有的模式感兴趣:

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

这将返回所有模式:

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

如果你想要一个清晰的方法,对课堂有用,并且只通过理解使用列表和字典,你可以这样做:

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}

如果一个数字是 mode,那么它在列表中出现的次数必须比 至少还有一个号码多,而且它必须是列表中唯一的数字 没有。因此,我重构了@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
#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)

扩展在列表为空时无法工作的 Community 应答,下面是 mode 的工作代码:

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

下面是你如何找到一个列表的平均值、中值和模式:

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

对于那些寻找最小模式的人,例如: 使用 numpy 的双模态分布的情况。

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

数据集的模式是/是该集中最频繁出现的成员。如果有两个成员最常以相同的次数出现,则数据有两种模式。这叫做双峰。如果有多于2个模式,那么数据将被称为 multimode。如果数据集中的所有成员出现的次数相同,则该数据集根本没有模式。以下函数 mode ()可以在给定的数据列表中查找 mode (s) :

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)
Out[4]: There is NO mode in the data set
# For a list of strings/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']

如果我们不想导入 numpypandas来调用这些包中的任何函数,那么为了得到相同的输出,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")

查找列表模式而不进行任何导入的简单代码:

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)

在多个模式的情况下,它应该返回最小节点。

也许可以试试下面这些。它是 O (n)并返回一个 float (或 int)列表。这是彻底的,自动测试。它使用 Collections.defaultdict,但我希望你不反对使用它。它也可以在 https://stromberg.dnsalias.org/~strombrg/stddev.html找到

def compute_mode(list_: typing.List[float]) -> typing.List[float]:
"""
Compute the mode of list_.


Note that the return value is a list, because sometimes there is a tie for "most common value".
                                                                        

See https://stackoverflow.com/questions/10797819/finding-the-mode-of-a-list
"""
if not list_:
raise ValueError('Empty list')
if len(list_) == 1:
raise ValueError('Single-element list')
value_to_count_dict: typing.DefaultDict[float, int] = collections.defaultdict(int)
for element in list_:
value_to_count_dict[element] += 1
count_to_values_dict = collections.defaultdict(list)
for value, count in value_to_count_dict.items():
count_to_values_dict[count].append(value)
counts = list(count_to_values_dict)
if len(counts) == 1:
raise ValueError('All elements in list are the same')
maximum_occurrence_count = max(counts)
if maximum_occurrence_count == 1:
raise ValueError('No element occurs more than once')
minimum_occurrence_count = min(counts)
if maximum_occurrence_count <= minimum_occurrence_count:
raise ValueError('Maximum count not greater than minimum count')
return count_to_values_dict[maximum_occurrence_count]

社区已经有了很多答案,其中一些使用了其他的功能,你不会想要的。
让我们创建 非常简单易懂函数。

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

例子

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

我的大脑是如何决定完全从头开始做这件事的。高效而简洁:)(jk 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)