Предположим, у меня есть следующий список на Python:
a = [1,2,3,1,2,1,1,1,3,2,2,1]
Как аккуратно найти самый частый номер в этом списке?
python
numpy
statistics
Как раз вовремя
источник
источник
np.bincount([1, 2, 3, 1, 2, 1, 1, 1, 3, 2, 2, 1]).argmax()
scipy.stats.mode
, хотя и менее общее.Counter(array).most_common(1)[0][0]
Вы можете использовать
Если один элемент встречается так же часто, как другой, этот код вернет только первый элемент.
источник
values[counts.argmax()]
вернется первое значение. Чтобы получить их все, мы можем использоватьvalues[counts == counts.max()]
.Если вы хотите использовать SciPy :
источник
Показатели (с использованием iPython) для некоторых решений можно найти здесь:
Лучше всего «max» с «set» для небольших массивов, таких как проблема.
По словам @David Sanders, если вы увеличите размер массива примерно до 100 000 элементов, алгоритм «max w / set» окажется наихудшим, тогда как метод «numpy bincount» будет лучшим.
источник
a = (np.random.rand(100000) * 1000).round().astype('int'); a_list = list(a)
), ваш алгоритм «max w / set» окажется наихудшим, тогда как метод «numpy bincount» будет лучшим. Я провел этот тест, используяa_list
собственный код Python и кодa
numpy, чтобы избежать потери результатов из-за затрат на сборку.Также, если вы хотите получить наиболее частое значение (положительное или отрицательное) без загрузки каких-либо модулей, вы можете использовать следующий код:
источник
max(set(lVals), key=lVals.count)
, который подсчитывает O (n) для каждого уникального элементаlVals
примерно на O (n ^ 2) (при условии O (n) уникальных элементы). Использованиеcollections.Counter(lVals).most_common(1)[0][0]
стандартной библиотеки, как предлагает JoshAdel , составляет всего O (n).Хотя большинство приведенных выше ответов полезны, если вам: 1) он нужен для поддержки неположительных целочисленных значений (например, с плавающей запятой или отрицательных целых чисел ;-)), и 2) не на Python 2.7 (который collections.Counter требует), и 3) предпочитают не добавлять зависимость scipy (или даже numpy) к вашему коду, тогда решение чисто на Python 2.6, которое является O (nlogn) (то есть эффективным), просто так:
источник
Мне нравится решение Джоша Аделя.
Но есть только одна загвоздка.
np.bincount()
Решение работает только на номера.Если у вас есть строки,
collections.Counter
решение подойдет вам.источник
Расширение этого метода применяется к поиску режима данных, в котором вам может понадобиться индекс фактического массива, чтобы увидеть, как далеко значение находится от центра распределения.
Не забудьте отказаться от режима, когда len (np.argmax (counts))> 1
источник
В Python 3 должно работать следующее:
источник
Начиная с
Python 3.4
, стандартная библиотека включаетstatistics.mode
функцию для возврата единственной наиболее распространенной точки данных.Если имеется несколько режимов с одинаковой частотой,
statistics.mode
возвращает первый встреченный.Начиная с
Python 3.8
,statistics.multimode
функция возвращает список наиболее часто встречающихся значений в том порядке, в котором они были впервые обнаружены:источник
Вот общее решение, которое можно применить вдоль оси, независимо от значений, используя чисто numpy. Я также обнаружил, что это намного быстрее, чем scipy.stats.mode, если есть много уникальных значений.
источник
Я недавно делаю проект и использую collections.Counter. (Что меня мучило).
На мой взгляд, счетчик в коллекциях работает очень плохо. Это просто класс-оболочка dict ().
Что еще хуже, если вы используете cProfile для профилирования его метода, вы должны увидеть много вещей «__missing__» и «__instancecheck__», которые тратят все время впустую.
Будьте осторожны при использовании most_common (), потому что каждый раз он будет вызывать сортировку, что делает его очень медленным. и если вы используете most_common (x), он вызовет сортировку кучи, что также будет медленным.
Кстати, у numpy bincount тоже есть проблема: если вы используете np.bincount ([1,2,4000000]), вы получите массив с 4000000 элементами.
источник