2015-02-22 7 views
100

In Python, ho un ndarray y che viene stampata come array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])Come contare l'occorrenza di determinati elementi in un narray in Python?

sto cercando di contare quante 0 e quanti 1 ci sono in questo array.

Ma quando si digita o y.count(0)y.count(1), si dice 'numpy.ndarray' oggetto non ha attributo 'count'

Cosa devo fare?

modo
+1

Non è possibile utilizzare la funzione somma e lunghezza, dal momento che si dispone solo di assi e zeri? – nikaltipar

risposta

179
>>> 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:

Usa 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}) 
+30

Un modo molto più veloce per ottenere la stessa cosa è usare ['np.unique'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.unique.html) con 'return_counts = True', es 'values, counts = np.unique (a, return_counts = True)' –

+2

Questo sarebbe '' ' unico, conteggi = numpy.unique (a, return_counts = True) dict (zip (unico, conteggi)) '' ' – shredding

+5

Se si desidera il dizionario,' dict (zip (* numpy.unique (a, return_counts = True))) ' –

6
y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]) 

Se si sa che sono solo 0 e 1:

np.sum(y) 

ti dà il numero di quelli. np.sum(1-y) fornisce gli zeri.

Per lieve generalità, se si desidera contare 0 e non pari a zero (ma forse 2 o 3):

np.count_nonzero(y) 

dà il numero di diverso da zero.

Ma se avete bisogno di qualcosa di più complicato, non credo che numpy fornirà una bella opzione count. In questo caso, andare a collezioni:

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

Questo comporta come un dict

collections.Counter(y)[0] 
> 8 
12

Convertire la matrice y per elencare l e poi fare l.count(1) e 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 
18

Per il vostro caso potresti anche esaminare 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 
3

userei np.where:

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

Si tratta di un passo in più, ma una soluzione più flessibile che sarebbe anche lavorare per le matrici 2D e filtri più complicato è quello di creare una maschera booleano e poi usa .sum() sulla maschera.

>>>>y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]) 
>>>>mask = y == 0 
>>>>mask.sum() 
8 
76

Cosa succede ad usare numpy.count_nonzero, qualcosa come

>>> 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 
+0

Questa risposta sembra migliore di quella con i più upvotes. – Alex

5

Che dire len(y[y==0]) e len(y[y==1])?

48

Personalmente, mi piacerebbe andare per: (y == 0).sum() e (y == 1).sum()

Ad es

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() 
+0

Questa risposta sembra migliore di quella con i più upvotes. – Alex

3

y.tolist().count(val)

con val 0 o 1

Poiché un elenco pitone ha una funzione nativa count, convertendo elencare prima di utilizzare tale funzione è una soluzione semplice.

0

Se non si desidera utilizzare NumPy o un centro di raccolta modulo è possibile utilizzare un dizionario:

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 

risultato:

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

Naturalmente è anche possibile utilizzare un'istruzione if/else . Penso che la funzione Counter faccia quasi la stessa cosa ma è più trasparente.

3

Ancora un'altra soluzione semplice potrebbe essere quella di utilizzare 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 

Non lasciate che il nome trarre in inganno, se lo si utilizza con il booleano proprio come nel esempio, farà il trucco.

1

Questo può essere fatto facilmente nel seguente metodo

y = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]) 
y.tolist().count(1) 
3

Onestamente lo trovo più semplice per convertire in una Serie panda o 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() 

O questo bel uno-liner suggerita da Robert Muil:

pd.Series([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]).value_counts() 
+2

Solo una nota: non è necessario il DataFrame o numpy, può passare direttamente da un elenco a una serie: 'pd.Series ([0, 0, 0, 1, 0, 1, 1, 0, 0, 0 , 0, 1]). Value_counts() ' –

+0

Impressionante, questa è una bella copertina. Big up – wordsforthewise

1

Una risposta generale e semplice sarebbe:

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

che si tradurrebbe in questo codice completo come 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 

Ora, se MyArray è in dimensioni multiple e si desidera contare il verificarsi di una distribuzione di valori in linea (= modello qui di seguito)

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

Come utilizzare np.unique?

In [75]: boo = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 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 
1

Dal momento che il ndarray contiene solo 0 e 1, è possibile utilizzare sum() per ottenere il verificarsi di 1s e len() - sum() per ottenere il verificarsi di 0.

num_of_ones = sum(array) 
num_of_zeros = len(array)-sum(array) 
2

Nessuno ha suggerito di utilizzare numpy.bincount(input, minlength) con minlength = np.size(input), ma sembra essere una buona soluzione, e sicuramente il più veloce :

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 

Questo è un aumento di velocità folle tra numpy.unique(x, return_counts=True) e numpy.bincount(x, minlength=np.size(x))!

0

Numpy ha un modulo per questo. Solo un piccolo trucco. Metti la tua matrice di input come bin.

numpy.histogram(y, bins=y) 

L'output è di 2 matrici. Uno con i valori stessi, l'altro con le frequenze corrispondenti.

2

Se si conosce esattamente il numero che si sta cercando, è possibile utilizzare quanto segue;

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

restituisce quante volte 2 si è verificato nell'array.