Como contar a ocorrência de determinado item em um ndarray no Python?




numpy multidimensional-array (21)

No Python, eu tenho um ndarray y impresso como array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

Estou tentando contar quantos 0s e quantos 1s existem nessa matriz.

Mas quando eu digito y.count(0) ou y.count(1) , ele diz

numpy.ndarray objeto numpy.ndarray não possui count atributos

O que devo fazer?


Answer #1
numpy.histogram(y, bins=y)

Apenas copiei o comentário de Seppo Enarvi aqui, que merece ser uma resposta adequada


Answer #2
>>> 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}

Maneira não-numpy :

Use 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})

Answer #3

Eu usaria np.where:

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

Answer #4

Para contar o número de ocorrências, você pode usar 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

Answer #5

Que tal usar numpy.count_nonzero , algo como

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

Answer #6

tire proveito dos métodos oferecidos por uma série:

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

Answer #7

Para entradas genéricas:

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

Irá gerar uma contagem:

np.mean(x)

E índices:

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

Answer #8

Honestamente, acho mais fácil converter para uma série de 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 este belo artigo sugerido por Robert Muil:

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

Answer #9

Isso envolve mais uma etapa, mas uma solução mais flexível que também funcionaria para matrizes 2D e filtros mais complicados é criar uma máscara booleana e usar .sum () na máscara.

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

Answer #10

Ainda outra solução simples pode ser usar 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

Não deixe o nome enganar você, se você o usar com o booleano, como no exemplo, ele fará o truque.


Answer #11

E quanto a len(y[y==0]) e len(y[y==1]) ?


Answer #12
 using numpy.count $ a = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1] $ np.count(a, 1) 

Answer #13

Ninguém sugeriu usar numpy.bincount(input, minlength) com minlength = np.size(input) , mas parece ser uma boa solução e, definitivamente, a mais rápida :

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

Essa é uma aceleração louca entre numpy.unique(x, return_counts=True) e numpy.bincount(x, minlength=np.max(x)) !


Answer #14

Você tem uma matriz especial com apenas 1 e 0 aqui. Então, um truque é usar

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

que fornece a porcentagem de 1s em sua matriz. Como alternativa, use

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

fornecerá o número absoluto de 1 e 0 em sua matriz.


Answer #15

Numpy tem um módulo para isso. Apenas um pequeno truque. Coloque sua matriz de entrada como caixas.

using numpy.count

$ a = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]

$ np.count(a, 1)

A saída são 2 matrizes. Um com os próprios valores, outro com as frequências correspondentes.


Answer #16

Converta sua matriz y para listar l seguida, 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 

Answer #17

Como seu ndarray contém apenas 0 e 1, você pode usar sum () para obter a ocorrência de 1s e len () - sum () para obter a ocorrência de 0s.

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

Answer #18

Isso pode ser feito facilmente no seguinte método

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

Answer #19

Você pode usar a compreensão de dicionário para criar uma linha única. Mais informações sobre a compreensão do dicionário podem ser encontradas aqui

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

Isso criará um dicionário com os valores em seu ndarray como chaves e as contagens dos valores como valores das chaves, respectivamente.

Isso funcionará sempre que você desejar contar ocorrências de um valor em matrizes desse formato.


Answer #20

Para o seu caso, você também pode procurar 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

Answer #21

Uma resposta geral e simples seria:

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

o que resultaria nesse código completo como exemplo

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

Agora, se MyArray está em várias dimensões e você deseja contar a ocorrência de uma distribuição de valores na linha (= padrão a seguir)

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




count