Finding the mode of a list

PythonMode

Python Problem Overview


Given a list of items, recall that the mode of the list is the item that occurs most often.

I would like to know how to create a function that can find the mode of a list but that displays a message if the list does not have a mode (e.g., all the items in the list only appear once). I want to make this function without importing any functions. I'm trying to make my own function from scratch.

Python Solutions


Solution 1 - Python

You can use the max function and a key. Have a look at python max function using 'key' and lambda expression.

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

Solution 2 - Python

You can use the Counter supplied in the collections package which has a mode-esque function

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

Note: Counter is new in python 2.7 and is not available in earlier versions.

Solution 3 - Python

Python 3.4 includes the method statistics.mode, so it is straightforward:

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

You can have any type of elements in the list, not just numeric:

>>> mode(["red", "blue", "blue", "red", "green", "red", "red"])
 'red'

Solution 4 - Python

Taking a leaf from some statistics software, namely SciPy and MATLAB, these just return the smallest most common value, so if two values occur equally often, the smallest of these are returned. Hopefully an example will help:

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

Is there any reason why you can 't follow this convention?

Solution 5 - Python

There are many simple ways to find the mode of a list in Python such as:

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

Or, you could find the max by its count

max(array, key = array.count)

The problem with those two methods are that they don't work with multiple modes. The first returns an error, while the second returns the first mode.

In order to find the modes of a set, you could use this function:

def mode(array):
    most = max(list(map(array.count, array)))
    return list(set(filter(lambda x: array.count(x) == most, array)))

Solution 6 - Python

Extending the Community answer that will not work when the list is empty, here is working code for mode:

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

Solution 7 - Python

In case you are interested in either the smallest, largest or all modes:

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

Solution 8 - Python

A little longer, but can have multiple modes and can get string with most counts or mix of datatypes.

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 

Solution 9 - Python

I wrote up this handy function to find the 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

Solution 10 - Python

Short, but somehow ugly:

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

Using a dictionary, slightly less ugly:

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

Solution 11 - Python

This function returns the mode or modes of a function no matter how many, as well as the frequency of the mode or modes in the dataset. If there is no mode (ie. all items occur only once), the function returns an error string. This is similar to A_nagpal's function above but is, in my humble opinion, more complete, and I think it's easier to understand for any Python novices (such as yours truly) reading this question to understand.

 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

Solution 12 - Python

This will return all 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

Solution 13 - Python

For a number to be a mode, it must occur more number of times than at least one other number in the list, and it must not be the only number in the list. So, I refactored @mathwizurd's answer (to use the difference method) as follows:

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

These tests pass successfully:

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

Solution 14 - Python

Mode of a data set is/are the member(s) that occur(s) most frequently in the set. If there are two members that appear most often with same number of times, then the data has two modes. This is called bimodal.

If there are more than 2 modes, then the data would be called multimodal. If all the members in the data set appear the same number of times, then the data set has no mode at all.

Following function modes() can work to find mode(s) in a given list of data:

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

Output:

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

If we do not want to import numpy or pandas to call any function from these packages, then to get this same output, modes() function can be written as:

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

Solution 15 - Python

Simple code that finds the mode of the list without any imports:

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)

In case of multiple modes, it should return the minimum node.

Solution 16 - Python

Why not just

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

This doesn't have a few error checks that it should have, but it will find the mode without importing any functions and will print a message if all values appear only once. It will also detect multiple items sharing the same maximum count, although it wasn't clear if you wanted that.

Solution 17 - Python

Here is how you can find mean,median and mode of a list:

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

Solution 18 - Python

For those looking for the minimum mode, e.g:case of bi-modal distribution, using numpy.

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

Solution 19 - Python

Okey! So community has already a lot of answers and some of them used another function and you don't want.
let we create our very simple and easily understandable function.

import numpy as np

#Declare Function Name
def calculate_mode(lst):

>Next step is to find Unique elements in list and thier respective frequency.

unique_elements,freq = np.unique(lst, return_counts=True)

>Get mode

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]

Solution 20 - Python

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

Solution 21 - Python

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

Solution 22 - Python

Here is a simple function that gets the first mode that occurs in a list. It makes a dictionary with the list elements as keys and number of occurrences and then reads the dict values to get the 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.")

Solution 23 - Python

If you want a clear approach, useful for classroom and only using lists and dictionaries by comprehension, you can do:

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}

Solution 24 - Python

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

Solution 25 - Python

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

Solution 26 - Python

Perhaps try the following. It is O(n) and returns a list of floats (or ints). It is thoroughly, automatically tested. It uses collections.defaultdict, but I'd like to think you're not opposed to using that. It can also be found at 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]

Solution 27 - Python

How my brain decided to do it completely from scratch. Efficient and concise :) (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)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbluelanternView Question on Stackoverflow
Solution 1 - PythonDavid DaoView Answer on Stackoverflow
Solution 2 - PythonChristian WittsView Answer on Stackoverflow
Solution 3 - PythonjabaldonedoView Answer on Stackoverflow
Solution 4 - PythonChrisView Answer on Stackoverflow
Solution 5 - PythonmathwizurdView Answer on Stackoverflow
Solution 6 - PythonKardi TeknomoView Answer on Stackoverflow
Solution 7 - PythontashuhkaView Answer on Stackoverflow
Solution 8 - PythontimpjohnsView Answer on Stackoverflow
Solution 9 - Pythonuser2975335View Answer on Stackoverflow
Solution 10 - PythonCarlView Answer on Stackoverflow
Solution 11 - Pythonuser4406935View Answer on Stackoverflow
Solution 12 - PythonTim OrtonView Answer on Stackoverflow
Solution 13 - PythonlifebalanceView Answer on Stackoverflow
Solution 14 - PythonshubhView Answer on Stackoverflow
Solution 15 - Pythonbaby_yodaView Answer on Stackoverflow
Solution 16 - PythonlxopView Answer on Stackoverflow
Solution 17 - PythonpankajView Answer on Stackoverflow
Solution 18 - PythonV3K3RView Answer on Stackoverflow
Solution 19 - PythonRaushan kumarView Answer on Stackoverflow
Solution 20 - PythonakshaynagpalView Answer on Stackoverflow
Solution 21 - PythonVenkata Prasanth TView Answer on Stackoverflow
Solution 22 - PythonSMS von der TannView Answer on Stackoverflow
Solution 23 - PythonMaría Frances GaskaView Answer on Stackoverflow
Solution 24 - Pythonuser9283073View Answer on Stackoverflow
Solution 25 - Pythonuser1464878View Answer on Stackoverflow
Solution 26 - PythondstrombergView Answer on Stackoverflow
Solution 27 - PythontothemaxView Answer on Stackoverflow