10 ответов:
если ваш список содержит все неотрицательные ints, вы должны взглянуть на numpy.bincounts:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html
а затем, вероятно, использовать np.argmax:
a = np.array([1,2,3,1,2,1,1,1,3,2,2,1]) counts = np.bincount(a) print np.argmax(counts)для более сложного списка (который, возможно, содержит отрицательные числа или нецелые значения), вы можете использовать
np.histogramаналогично. Кроме того, если вы просто хотите работать в python без использования numpy,collections.Counter- это хороший способ обработки такого рода данных.from collections import Counter a = [1,2,3,1,2,1,1,1,3,2,2,1] b = Counter(a) print b.most_common(1)
вы можете использовать
(values,counts) = np.unique(a,return_counts=True) ind=np.argmax(counts) print values[ind] # prints the most frequent elementЕсли какой-то элемент встречается так же часто, как и другой, этот код возвращает только первый элемент.
Если вы используете составляющей:
>>> from scipy.stats import mode >>> mode([1,2,3,1,2,1,1,1,3,2,2,1]) (array([ 1.]), array([ 6.])) >>> most_frequent = mode([1,2,3,1,2,1,1,1,3,2,2,1])[0][0] >>> most_frequent 1.0
производительность (с использованием iPython) для некоторых решений, найденных здесь:
>>> # small array >>> a = [12,3,65,33,12,3,123,888000] >>> >>> import collections >>> collections.Counter(a).most_common()[0][0] 3 >>> %timeit collections.Counter(a).most_common()[0][0] 100000 loops, best of 3: 11.3 µs per loop >>> >>> import numpy >>> numpy.bincount(a).argmax() 3 >>> %timeit numpy.bincount(a).argmax() 100 loops, best of 3: 2.84 ms per loop >>> >>> import scipy.stats >>> scipy.stats.mode(a)[0][0] 3.0 >>> %timeit scipy.stats.mode(a)[0][0] 10000 loops, best of 3: 172 µs per loop >>> >>> from collections import defaultdict >>> def jjc(l): ... d = defaultdict(int) ... for i in a: ... d[i] += 1 ... return sorted(d.iteritems(), key=lambda x: x[1], reverse=True)[0] ... >>> jjc(a)[0] 3 >>> %timeit jjc(a)[0] 100000 loops, best of 3: 5.58 µs per loop >>> >>> max(map(lambda val: (a.count(val), val), set(a)))[1] 12 >>> %timeit max(map(lambda val: (a.count(val), val), set(a)))[1] 100000 loops, best of 3: 4.11 µs per loop >>>лучше всего "Макс" с "set"
хотя большинство ответов выше полезны, в случае, если вы: 1) нужно, чтобы он поддерживал неположительные целочисленные значения (например, поплавки или отрицательные целые числа ; -)), и 2) не на Python 2.7 (какие коллекции.Счетчик требует), и 3) предпочитайте не добавлять зависимость scipy( или даже numpy) к вашему коду, тогда чисто python 2.6 решение, которое является O (nlogn) (т. е. эффективным), просто так:
from collections import defaultdict a = [1,2,3,1,2,1,1,1,3,2,2,1] d = defaultdict(int) for i in a: d[i] += 1 most_frequent = sorted(d.iteritems(), key=lambda x: x[1], reverse=True)[0]
кроме того, если вы хотите получить наиболее частое значение(положительное или отрицательное) без загрузки каких-либо модулей, вы можете использовать следующий код:
lVals = [1,2,3,1,2,1,1,1,3,2,2,1] print max(map(lambda val: (lVals.count(val), val), set(lVals)))
мне нравится решение Джошаделя.
но есть только одна загвоздка.
The
np.bincount()решение работает только на цифры.Если у вас есть строки
collections.Counterрешение будет работать для вас.
расширения этот метод, применяется к нахождению режима данных, где вам может понадобиться индекс массива, чтобы увидеть, как далеко значение от центра распределения.
(_, idx, counts) = np.unique(a, return_index=True, return_counts=True) index = idx[np.argmax(counts)] mode = a[index]Не забудьте отменить режим, когда len (np.argmax(счетчики)) > 1
вот общее решение, которое может быть применено вдоль оси, независимо от значений, используя чисто numpy. Я также обнаружил, что это намного быстрее, чем scipy.статистика.режим, если есть много уникальных значений.
import numpy def mode(ndarray, axis=0): # Check inputs ndarray = numpy.asarray(ndarray) ndim = ndarray.ndim if ndarray.size == 1: return (ndarray[0], 1) elif ndarray.size == 0: raise Exception('Cannot compute mode on empty array') try: axis = range(ndarray.ndim)[axis] except: raise Exception('Axis "{}" incompatible with the {}-dimension array'.format(axis, ndim)) # If array is 1-D and numpy version is > 1.9 numpy.unique will suffice if all([ndim == 1, int(numpy.__version__.split('.')[0]) >= 1, int(numpy.__version__.split('.')[1]) >= 9]): modals, counts = numpy.unique(ndarray, return_counts=True) index = numpy.argmax(counts) return modals[index], counts[index] # Sort array sort = numpy.sort(ndarray, axis=axis) # Create array to transpose along the axis and get padding shape transpose = numpy.roll(numpy.arange(ndim)[::-1], axis) shape = list(sort.shape) shape[axis] = 1 # Create a boolean array along strides of unique values strides = numpy.concatenate([numpy.zeros(shape=shape, dtype='bool'), numpy.diff(sort, axis=axis) == 0, numpy.zeros(shape=shape, dtype='bool')], axis=axis).transpose(transpose).ravel() # Count the stride lengths counts = numpy.cumsum(strides) counts[~strides] = numpy.concatenate([[0], numpy.diff(counts[~strides])]) counts[strides] = 0 # Get shape of padded counts and slice to return to the original shape shape = numpy.array(sort.shape) shape[axis] += 1 shape = shape[transpose] slices = [slice(None)] * ndim slices[axis] = slice(1, None) # Reshape and compute final counts counts = counts.reshape(shape).transpose(transpose)[slices] + 1 # Find maximum counts and return modals/counts slices = [slice(None, i) for i in sort.shape] del slices[axis] index = numpy.ogrid[slices] index.insert(axis, numpy.argmax(counts, axis=axis)) return sort[index], counts[index]
Я недавно делаю проект и использую коллекции.Счетчик.(Что мучило меня).
счетчик в коллекциях имеют очень очень плохую производительность, на мой взгляд. Это просто класс обертывания dict ().
Что еще хуже, если вы используете cProfile для профилирования своего метода, вы должны увидеть много "__missing__ " и " __instancecheck__", которые тратят все время.
будьте осторожны, используя его most_common (), потому что каждый раз он будет вызывать сортировку, которая делает его крайне медленный. и если вы используете most_common (x), он вызовет сортировку кучи, которая также медленная.
кстати, у bincount numpy также есть проблема: если вы используете np.bincount ([1,2,4000000]), вы получите массив с 4000000 элементов.
Comments