Supposons que j'ai la liste suivante en python:
a = [1,2,3,1,2,1,1,1,3,2,2,1]
Comment trouver le numéro le plus fréquent dans cette liste de manière ordonnée?
Si votre liste contient tous les éléments non négatifs, consultez numpy.bincounts:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html
et puis probablement utiliser 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)
Pour une liste plus compliquée (pouvant contenir des nombres négatifs ou des valeurs non entières), vous pouvez utiliser np.histogram
de la même manière. Si vous voulez simplement travailler en python sans utiliser numpy, collections.Counter
est un bon moyen de gérer ce type de données.
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)
Vous pouvez utiliser
(values,counts) = np.unique(a,return_counts=True)
ind=np.argmax(counts)
print values[ind] # prints the most frequent element
Si un élément est aussi fréquent qu'un autre, ce code ne renverra que le premier élément.
Si vous êtes prêt à utiliser SciPy :
>>> 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
>>> # 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
>>>
Le mieux est "max" avec "set"
Bien que la plupart des réponses ci-dessus soient utiles, dans le cas où vous: 1) en avez besoin pour prendre en charge les valeurs d'entier non positif (par exemple, les nombres entiers négatifs ou négatifs ;-)), et 2) ne sont pas en Python. 2.7 (que collections.Counter nécessite), et 3) préfèrent ne pas ajouter la dépendance de scipy (ou même numpy) à votre code, puis à une solution purement python 2.6 qui est O(nlogn) (c'est-à-dire , efficace) est juste ceci:
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]
De plus, si vous voulez obtenir la valeur la plus fréquente (positive ou négative) sans charger de module, vous pouvez utiliser le code suivant:
lVals = [1,2,3,1,2,1,1,1,3,2,2,1]
print max(map(lambda val: (lVals.count(val), val), set(lVals)))
J'aime la solution de JoshAdel.
Mais il n'y a qu'une seule prise.
La solution np.bincount()
ne fonctionne que sur les chiffres.
Si vous avez des chaînes, la solution collections.Counter
fonctionnera pour vous.
Développer sur cette méthode , appliquée à la recherche du mode des données où vous pouvez avoir besoin de l'index du tableau réel pour voir à quelle distance se trouve la valeur du centre de la distribution.
(_, idx, counts) = np.unique(a, return_index=True, return_counts=True)
index = idx[np.argmax(counts)]
mode = a[index]
N'oubliez pas de jeter le mode quand len (np.argmax (count))> 1
Dans Python 3, les éléments suivants devraient fonctionner:
max(set(a), key=lambda x: a.count(x))
Voici une solution générale qui peut être appliquée le long d’un axe, quelles que soient les valeurs, en utilisant purement numpy. J'ai également constaté que cela est beaucoup plus rapide que scipy.stats.mode s'il existe de nombreuses valeurs uniques.
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]