2015-02-22 13 views
100

W Pythonie mam ndarray y który jest drukowany jako array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])Jak liczyć wystąpienie określonego elementu w ndarray w Pythonie?

Próbuję policzyć ile 0 i 1 ile istnieją w tej tablicy.

Ale kiedy wpisać y.count(0) lub y.count(1), mówi 'numpy.ndarray' obiekt ma bez atrybutu „count”

Co należy zrobić?

+1

Nie możesz użyć funkcji sumy i długości, ponieważ masz tylko asy i zera? – nikaltipar

Odpowiedz

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} 

dla numpy sposób:

Zastosowanie 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

Znacznie szybszy "czysty numpy" sposób osiągnięcia tego samego jest użycie ['np.unique'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.unique.html) z 'return_counts = True', np 'Wartości, liczy = np.unique (a, return_counts = True)' –

+2

To byłoby '' ' wyjątkowy, liczy = numpy.unique (a, return_counts = True) DICT (zip (unikalna, liczy)) '' ' – shredding

+5

Jeśli chcesz słownik,' dict (zip (* numpy.unique (a, return_counts = True))) ' –

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

Jeśli wiadomo, że są one po prostu 0 i 1:

np.sum(y) 

daje liczbę jedynek. np.sum(1-y) podaje zer.

Na lekkim ogólności, jeśli chcesz liczyć 0 a nie zero (ale prawdopodobnie 2 lub 3):

np.count_nonzero(y) 

daje liczbę różną od zera.

Ale jeśli potrzebujesz czegoś bardziej skomplikowanego, nie sądzę, że numpy zapewni miłą opcję count. W takim przypadku, przejdź do kolekcji:

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

ten zachowuje się jak dict

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

Konwersja tablicy y do listy l a następnie zrobić l.count(1) i 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

Twoim przypadku możesz również przejrzeć 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

użyję np.where:

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

Polega ona jeszcze jeden krok, ale bardziej elastyczne rozwiązanie, które również działają 2D tablic i bardziej skomplikowanych filtrów jest stworzenie logiczną maskę a następnie użyj .sum() na masce.

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

Co na temat korzystania numpy.count_nonzero, coś

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

Ta odpowiedź wydaje się być lepsza niż ta, która zawiera najwięcej głosów. – Alex

5

Co len(y[y==0]) i len(y[y==1])?

48

Osobiście poszedłbym do: (y == 0).sum() i (y == 1).sum()

Np

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

Ta odpowiedź wydaje się być lepsza niż ta, która zawiera najwięcej głosów upvotes. – Alex

3

y.tolist().count(val)

z val 0 lub 1

Ponieważ lista pyton ma funkcję natywną count, konwersja do listy, aby za pomocą tej funkcji jest prostym rozwiązaniem.

0

Jeśli nie chcesz korzystać z numpy lub zbiory modułu można użyć słownika:

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 

wynik:

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

Oczywiście można również użyć if/else . Myślę, że funkcja Licznik robi prawie to samo, ale jest to bardziej przejrzyste.

3

Kolejny prostym rozwiązaniem może być użycie 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 

Nie daj nazwa Cię w błąd, jeśli używasz go z logiczną jak na przykład, da rade.

1

Można to łatwo zrobić w następujący sposób

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

Szczerze uważam, że to najłatwiejszy do konwersji do serialu pandy lub 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() 

Lub ten miły jedną wkładką sugerowanej przez Robert Muil:

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

Po prostu: nie potrzebujesz DataFrame ani numpy, możesz przejść bezpośrednio z listy do Serii: 'pd.Series ([0, 0, 0, 1, 0, 1, 1, 0, 0, 0 , 0, 1]). Value_counts() ' –

+0

Wspaniale, to fajny jednolinijkowy. Duży – wordsforthewise

1

Ogólna i prosta odpowiedź brzmi:

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

co skutkowałoby w tym pełnego kodu jako 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 

Teraz jeśli MyArray jest w wielu wymiarach i chcesz policzyć wystąpienie rozkładu wartości w wierszu (= wzór Hereafter)

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

Jak korzystać z 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

Ponieważ ndarray zawiera tylko 0 i 1, można użyć sumy(), aby uzyskać wystąpienie 1s i len() - suma(), aby uzyskać wystąpienie 0s.

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

Nikt zalecane, aby użyć numpy.bincount(input, minlength) z minlength = np.size(input), ale wydaje się być dobrym rozwiązaniem, a na pewno w najszybszym:

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 

To szalone przyspieszenie między numpy.unique(x, return_counts=True) i numpy.bincount(x, minlength=np.size(x))!

0

Numpy ma moduł do tego. Tylko mały hack. Umieść tablicę wejściową jako pojemniki.

numpy.histogram(y, bins=y) 

Dane wyjściowe to 2 tablice. Jeden z wartościami, inny z odpowiednimi częstotliwościami.

2

Jeśli wiesz dokładnie, którego numeru szukasz, możesz skorzystać z następujących opcji;

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

zwraca ile razy 2 wystąpiło w twojej tablicy.

Powiązane problemy