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 0
s et combien de 1
s 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'attributcount
Que devrais-je faire?
_>>> 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})
_
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
_
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()
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
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
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
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.
Qu'en est-il de len(y[y==0])
et len(y[y==1])
?
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()
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.
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
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.
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))
!
J'utiliserais np.where:
how_many_0 = len(np.where(a==0.)[0])
how_many_1 = len(np.where(a==1.)[0])
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.
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
É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)
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)
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
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]}
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
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.
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.
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.