Comment compter l'occurrence de certains éléments dans un ndarray en Python?

En Python, j'ai un ndarray y qui est imprimé comme array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

Je suis en train de compter combien de 0s et combien de 1s sont là dans ce tableau.

, Mais quand je tape y.count(0) ou y.count(1), dit-il

numpy.ndarray l'objet n'a pas d'attribut count

Que dois-je faire?

162
demandé sur Ivan 2015-02-23 01:05:48

20 réponses

>>> a = numpy.array([0, 3, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0, 1, 3, 4])
>>> unique, counts = numpy.unique(a, return_counts=True)
>>> dict(zip(unique, counts))
{0: 7, 1: 4, 2: 1, 3: 2, 4: 1}

Non-numpy façon :

Utiliser collections.Counter;

>> import collections, numpy

>>> a = numpy.array([0, 3, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0, 1, 3, 4])
>>> collections.Counter(a)
Counter({0: 7, 1: 4, 3: 2, 2: 1, 4: 1})
275
répondu ozgur 2018-01-24 09:31:41

Que penser de l'utilisation numpy.count_nonzero, quelque chose comme

>>> import numpy as np
>>> y = np.array([1, 2, 2, 2, 2, 0, 2, 3, 3, 3, 0, 0, 2, 2, 0])

>>> np.count_nonzero(y == 1)
1
>>> np.count_nonzero(y == 2)
7
>>> np.count_nonzero(y == 3)
3
126
répondu Aziz Alto 2017-10-12 14:33:02

Personnellement, j'irais pour: (y == 0).sum() et (y == 1).sum()

Par exemple

import numpy as np
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
num_zeros = (y == 0).sum()
num_ones = (y == 1).sum()
76
répondu Gus Hecht 2016-05-05 20:51:53

Pour votre cas, vous pouvez également regarder dans numpy.bincount

In [56]: a = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

In [57]: np.bincount(a)
Out[57]: array([8, 4])  #count of zeros is at index 0 : 8
                        #count of ones is at index 1 : 4
24
répondu Akavall 2015-02-22 23:45:06

Convertissez votre tableau y en list l puis faites l.count(1) et l.count(0)

>>> y = numpy.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
>>> l = list(y)
>>> l.count(1)
4
>>> l.count(0)
8 
14
répondu Milind Dumbare 2015-02-22 22:19:15
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

Si vous savez qu'ils sont juste 0 et 1:

np.sum(y)

Vous Donne le nombre de ceux. np.sum(1-y) donne les zéros.

Pour une légère généralité, si vous voulez compter 0 et non zéro (mais éventuellement 2 ou 3):

np.count_nonzero(y)

Donne le nombre de non nul.

Mais si vous avez besoin de quelque chose de plus compliqué, Je ne pense pas que numpy fournira une belle option count. Dans ce cas, allez dans collections:

import collections
collections.Counter(y)
> Counter({0: 8, 1: 4})

Cela se comporte comme un dict

collections.Counter(y)[0]
> 8
10
répondu Joel 2015-02-22 22:15:52

Si vous savez exactement quel numéro vous recherchez, vous pouvez utiliser ce qui suit;

lst = np.array([1,1,2,3,3,6,6,6,3,2,1])
(lst == 2).sum()

Renvoie combien de fois 2 est survenu dans votre tableau.

9
répondu CanCeylan 2017-11-22 10:31:40

Qu'en est-il de len(y[y==0]) et len(y[y==1])?

6
répondu Anas 2016-03-11 18:29:51

Encore une autre solution simple pourrait être d'utiliser numpy.count_nonzero():

import numpy as np
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
y_nonzero_num = np.count_nonzero(y==1)
y_zero_num = np.count_nonzero(y==0)
y_nonzero_num
4
y_zero_num
8

Ne laissez pas le nom vous tromper, si vous l'utilisez avec le booléen comme dans l'exemple, il fera l'affaire.

4
répondu NaZo 2016-10-04 09:30:05

Honnêtement, je trouve plus facile de convertir en une série pandas ou DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({'data':np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])})
print df['data'].value_counts()

Ou ce joli one-liner suggéré par Robert Muil:

pd.Series([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]).value_counts()
4
répondu wordsforthewise 2017-09-11 17:41:51

J'utiliserais np.où:

how_many_0 = len(np.where(a==0.)[0])
how_many_1 = len(np.where(a==1.)[0])
3
répondu MaxG 2015-10-19 14:15:59

y.tolist().count(val)

Avec val 0 ou 1

Comme une liste python a une fonction native count, la conversion en liste avant d'utiliser cette fonction est une solution simple.

3
répondu michael 2016-05-19 19:14:57

Pour compter le nombre d'occurrences, vous pouvez utiliser np.unique(array, return_counts=True):

In [75]: boo = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

# use bool value `True` or equivalently `1`
In [77]: uniq, cnts = np.unique(boo, return_counts=1)
In [81]: uniq
Out[81]: array([0, 1])   #unique elements in input array are: 0, 1

In [82]: cnts
Out[82]: array([8, 4])   # 0 occurs 8 times, 1 occurs 4 times
3
répondu kmario23 2018-10-04 23:37:52

Personne N'a suggéré d'utiliser numpy.bincount(input, minlength) avec minlength = np.size(input), mais il semble être une bonne solution, et certainement le plus rapide:

In [1]: choices = np.random.randint(0, 100, 10000)

In [2]: %timeit [ np.sum(choices == k) for k in range(min(choices), max(choices)+1) ]
100 loops, best of 3: 2.67 ms per loop

In [3]: %timeit np.unique(choices, return_counts=True)
1000 loops, best of 3: 388 µs per loop

In [4]: %timeit np.bincount(choices, minlength=np.size(choices))
100000 loops, best of 3: 16.3 µs per loop

C'est une accélération folle entre numpy.unique(x, return_counts=True) et numpy.bincount(x, minlength=np.size(x))!

2
répondu Næreen 2017-03-17 16:19:25

Cela implique une étape de plus, mais une solution plus flexible qui fonctionnerait également pour les tableaux 2d et les filtres plus compliqués consiste à créer un masque booléen puis à l'utiliser .sum() sur le masque.

>>>>y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
>>>>mask = y == 0
>>>>mask.sum()
8
1
répondu Thomas 2015-12-24 22:35:59

Cela peut être fait facilement dans la méthode suivante

y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
y.tolist().count(1)
1
répondu user7055304 2016-10-22 00:25:00

Une réponse générale et simple serait:

numpy.sum(MyArray==x)   # sum of a binary list of the occurence of x (=0 or 1) in MyArray

Qui aboutirait à ce code complet comme exemple

import numpy
MyArray=numpy.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])  # array we want to search in
x=0   # the value I want to count (can be iterator, in a list, etc.)
numpy.sum(MyArray==0)   # sum of a binary list of the occurence of x in MyArray

Maintenant, si MyArray est dans plusieurs dimensions et que vous voulez compter l'occurrence d'une distribution de valeurs en ligne (=motif ci-après)

MyArray=numpy.array([[6, 1],[4, 5],[0, 7],[5, 1],[2, 5],[1, 2],[3, 2],[0, 2],[2, 5],[5, 1],[3, 0]])
x=numpy.array([5,1])   # the value I want to count (can be iterator, in a list, etc.)
temp = numpy.ascontiguousarray(MyArray).view(numpy.dtype((numpy.void, MyArray.dtype.itemsize * MyArray.shape[1])))  # convert the 2d-array into an array of analyzable patterns
xt=numpy.ascontiguousarray(x).view(numpy.dtype((numpy.void, x.dtype.itemsize * x.shape[0])))  # convert what you search into one analyzable pattern
numpy.sum(temp==xt)  # count of the searched pattern in the list of patterns
1
répondu sol 2016-11-18 16:19:22

Puisque votre ndarray ne contient que 0 et 1, vous pouvez utiliser sum() pour obtenir l'occurrence de 1s et Len () - sum () pour obtenir l'occurrence de 0s.

num_of_ones = sum(array)
num_of_zeros = len(array)-sum(array)
1
répondu Sabeer Ebrahim 2017-01-12 17:40:05

Si vous ne voulez pas utiliser numpy ou un module de collections, vous pouvez utiliser un dictionnaire:

d = dict()
a = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
for item in a:
    try:
        d[item]+=1
    except KeyError:
        d[item]=1

Résultat:

>>>d
{0: 8, 1: 4}

Bien sûr, vous pouvez également utiliser une instruction if/else. Je pense que la fonction de compteur fait presque la même chose mais c'est plus transparent.

0
répondu JLT 2016-07-08 14:41:38

Numpy a un module pour cela. Juste un petit hack. Mettez votre tableau d'entrée en tant que bacs.

numpy.histogram(y, bins=y)

Les sorties sont 2 tableaux. L'un avec les valeurs elles-mêmes, l'autre avec les fréquences correspondantes.

0
répondu Ishan Tomar 2017-04-26 10:37:05