No Unique Mode; Found 2 Equally Common Values

No Unique Mode; Found 2 Equally Common Values

I'm using statistics.mode([1, 1, 2, 2, 3]) to find the mode, but I get:

no unique mode; found 2 equally common values

When more than one mode is found, how can I output either 1 or 2?

0

8 Answers

Note that in Python 3.8 the behaviour of statistics.mode has changed:

Changed in version 3.8: Now handles multimodal datasets by returning the first mode encountered. Formerly, it raised StatisticsError when more than one mode was found.

In your example:

from statistics import mode

mode([1, 1, 2, 2, 3])
# 1

Also starting in Python 3.8, you can alternatively use statistics.multimode to return the list of the most frequently occurring values in the order they were first encountered:

from statistics import multimode

multimode([1, 1, 2, 2, 3])
# [1, 2]
1
from scipy import stats as s
a=[1,1,2,2,3]
print(int(s.mode(a)[0]))
1
from collections import Counter
c = Counter([1,1,2,2,3])
c.most_common(1)
# output
>>> [(1,2)] #the key 1, 2 occurrences.

From the docs:

"most_common([n]): Returns a list of the n most common elements and their counts from the most common to the least. Elements with equal counts are ordered arbitrarily"

Try this to find the max values as mode when no unique mode:

max([p[0] for p in statistics._counts([1, 1, 2, 2, 3])])
1

Try this function, which finds the max values as mode when no unique mode:

import statistics
def find_max_mode(list1):
    list_table = statistics._counts(list1)
    len_table = len(list_table)

    if len_table == 1:
        max_mode = statistics.mode(list1)
    else:
        new_list = []
        for i in range(len_table):
            new_list.append(list_table[i][0])
        max_mode = max(new_list) # use the max value here
    return max_mode

if __name__ == '__main__':
    a = [1,1,2,2,3]
    print(find_max_mode(a)) # print 2

For example:

lst = [1, 1, 2, 2, 3]

# test for count lst elements
lst_count = [[x, lst.count(x)] for x in set(lst)]
print lst_count
# [[1, 2], [2, 2], [3, 1]]

# remove count <= 1
lst_count = [x for x in set(lst) if lst.count(x) > 1]
print lst_count
# [1, 2]

# get 1 or 2 by index
print lst_count[0], lst_count[1]
# 1 2

Another way:

from collections import Counter

# change lst elements to str, for more readable
lst = ['a', 'a', 'b', 'b', 'c']

# get a dict, key is the elements in lst, value is count of the element
d_mem_count = Counter(lst)
print d_mem_count
# Counter({'a': 2, 'b': 2, 'c': 1})

for k in d_mem_count.keys():
    if d_mem_count[k] > 1:
        print k

# output as below
# a
# b
def MultiModeCalc(data):
    """
    set(data) -> discards duplicated values

    list(map(lambda x: data.count(x), set(data))))) -> counting how many of 
    each value there are

    dict(zip(set(data), list(map(lambda x: data.count(x), set(data))))) -> 
    making a dictionary by zipping all unique values(as keys) with their 
    frequency in the data(as values)

    return [i for i in multimode if multimode[i] == max(multimode.values())] 
    -> returning a list of the values that are most frequent in the data 
    """
    multimode = dict(zip(set(data), list(map(lambda x: data.count(x), set(data)))))
    return [i for i in multimode if multimode[i] == max(multimode.values())]
dataset = [1,2,5,6,3,7,2,3,9,1,10,3,1,2,9,9]
print(MultiModeCalc(dataset))
# [1, 2, 3, 9]

A DRY answer.

1

I just faced the same issue. This how I solved it pretty simply:

def most_element(liste):
    numeral=[[liste.count(nb), nb] for nb in liste]
    numeral.sort(key=lambda x:x[0], reverse=True)
    return(numeral[0][1])

Not sure this the most elegant way but it does the job :). Hope it will help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Maya Lin-Takahashi
Author

Maya Lin-Takahashi

Maya is a hardware enthusiast who tests and reviews smart home devices, smartphones, wearables, and audio gear. She focuses on practical consumer value and build quality.