web-dev-qa-db-fra.com

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

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

J'essaie 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), il est écrit

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

Que devrais-je faire?

276
mflowww
_>>> 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}
_

Manière non numpy :

Utilisez 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})
_
449
ozgur

Qu'en est-il de l'utilisation de 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
_
197
Aziz Alto

Personnellement, je choisirais: (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()
107
Gus Hecht

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
30
Akavall

Convertissez votre tableau y en liste l, puis exécutez 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 
17
Milind Dumbare
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

Si vous savez qu'ils ne sont que 0 et 1:

np.sum(y)

vous donne le nombre d'un. np.sum(1-y) donne les zéros.

Pour une légère généralité, si vous voulez compter 0 et non pas 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 option Nice count. Dans ce cas, accédez aux collections:

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

Cela se comporte comme un dict

collections.Counter(y)[0]
> 8
15
Joel

Si vous savez exactement quel numéro vous recherchez, vous pouvez utiliser le code suivant:

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

retourne combien de fois 2 s'est produit dans votre tableau.

13
CanCeylan

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

6
Anas

Honnêtement, je trouve plus facile de convertir en pandas Series 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 Nice one-liner suggéré par Robert Muil:

pd.Series([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]).value_counts()
6
wordsforthewise

y.tolist().count(val)

avec val 0 ou 1

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

6
michael

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
5
kmario23

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 induire en erreur, si vous l'utilisez avec le booléen comme dans l'exemple, cela fera l'affaire.

5
NaZo

Personne n'a suggéré d'utiliser numpy.bincount(input, minlength) avec minlength = np.size(input), mais cela 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 folle accélération entre numpy.unique(x, return_counts=True) et numpy.bincount(x, minlength=np.max(x))!

5
Næreen

J'utiliserais np.where:

how_many_0 = len(np.where(a==0.)[0])
how_many_1 = len(np.where(a==1.)[0])
4
MaxG

Vous pouvez utiliser la compréhension du dictionnaire pour créer une ligne parfaite. En savoir plus sur la compréhension du dictionnaire peut être trouvé ici

>>>counts = {int(value): list(y).count(value) for value in set(y)}
>>>print(counts)
{0: 8, 1: 4}

Cela créera un dictionnaire avec les valeurs de votre ndarray en tant que clés et les comptes des valeurs en tant que valeurs des clés respectivement.

Cela fonctionnera chaque fois que vous voudrez compter les occurrences d'une valeur dans des tableaux de ce format.

2
CB Madsen

profiter des méthodes offertes par une série:

>>> import pandas as pd
>>> y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
>>> pd.Series(y).value_counts()
0    8
1    4
dtype: int64
1

Étant donné que votre ndarray ne contient que 0 et 1, vous pouvez utiliser sum () pour obtenir l'occurrence de 1 et len ​​() - sum () pour obtenir l'occurrence de 0.

num_of_ones = sum(array)
num_of_zeros = len(array)-sum(array)
1
Sabeer Ebrahim

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
user7055304

Une réponse simple et générale 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 dimensions multiples 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
sol

Pour les entrées génériques:

x = np.array([11, 2, 3, 5, 3, 2, 16, 10, 10, 3, 11, 4, 5, 16, 3, 11, 4])
n = {i:len([j for j in np.where(x==i)[0]]) for i in set(x)}
ix = {i:[j for j in np.where(x==i)[0]] for i in set(x)}

Produira un compte:

{2: 2, 3: 4, 4: 2, 5: 2, 10: 2, 11: 3, 16: 2}

Et des indices:

{2: [1, 5],
3: [2, 4, 9, 14],
4: [11, 16],
5: [3, 12],
10: [7, 8],
11: [0, 10, 15],
16: [6, 13]}
0
deckard

Cela implique une étape supplémentaire, mais une solution plus flexible qui fonctionnerait également pour les tableaux 2D et les filtres plus complexes consiste à créer un masque booléen, puis à 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
0
Thomas

Vous avez un tableau spécial avec seulement 1 et 0 ici. Donc, une astuce consiste à utiliser

np.mean(x)

ce qui vous donne le pourcentage de 1 dans votre tableau. Sinon, utilisez

np.sum(x)
np.sum(1-x)

vous donnera le nombre absolu de 1 et 0 dans votre tableau.

0
CathyQian

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

numpy.histogram(y, bins=y)

La sortie est 2 tableaux. L'une avec les valeurs mêmes, l'autre avec les fréquences correspondantes.

0
Ishan Tomar

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 Counter fait presque la même chose mais que cela est plus transparent.

0
JLT