Hoe tel je het voorkomen van een bepaald item in een ndarray?

In Python heb ik een ndarray y
dat wordt afgedrukt als array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])

Ik probeer te tellen hoeveel 0en en hoeveel 1en er in deze array zitten.

Maar als ik y.count(0)of y.count(1)typ, staat er

numpy.ndarrayobject heeft geen attribuut count

Wat moet ik doen?


Antwoord 1, autoriteit 100%

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}

Niet-numpy manier:

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

Antwoord 2, autoriteit 41%

Hoe zit het met het gebruik van numpy.count_nonzero, zoiets als

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

Antwoord 3, autoriteit 21%

Persoonlijk zou ik gaan voor:
(y == 0).sum()EN (y == 1).sum()

b.g

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

Antwoord 4, Autoriteit 6%

Voor uw geval kunt u ook onderzoeken in 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

Antwoord 5, Autoriteit 3%

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

Als u weet dat ze gewoon 0en 1zijn:

np.sum(y)

geeft u het aantal. np.sum(1-y)geeft de nullen.

Voor kleine algemeenheid, als u wilt tellen 0en niet nul (maar mogelijk 2 of 3):

np.count_nonzero(y)

geeft het aantal niet-nul.

Maar als je iets gecompliceerder nodig hebt, denk ik niet dat Numpy een leuke count-optie zal bieden. Ga in dat geval naar collecties:

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

Dit gedraagt ​​zich als een dict

collections.Counter(y)[0]
> 8

Antwoord 6, autoriteit 3%

Converteer uw array ynaar len voer vervolgens l.count(1)en 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 

Antwoord 7, autoriteit 2%

Als u precies weet welk nummer u zoekt, kunt u het volgende gebruiken;

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

retourneert hoe vaak 2 is voorgekomen in uw array.


Antwoord 8

Niemand heeft voorgesteld om numpy.bincount(input, minlength)met minlength = np.size(input), maar het lijkt een goede oplossing te zijn, en zeker de snelste:

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

Dat is een waanzinnige versnelling tussen numpy.unique(x, return_counts=True)en numpy.bincount(x, minlength=np.max(x))!


Antwoord 9

Eerlijk gezegd vind ik het het gemakkelijkst om te converteren naar een panda-serie of 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()

of deze mooie one-liner voorgesteld door Robert Muil:

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

Antwoord 10

Hoe zit het met len(y[y==0])en len(y[y==1])?


Antwoord 11

y.tolist().count(val)

met VAL 0 of 1

Omdat een Python-lijst een native functie heeft count, het converteren naar lijst voordat u deze functie gebruikt een eenvoudige oplossing.


Antwoord 12

Ik zou NP.WAAR gebruiken:

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

Antwoord 13

Nog een andere eenvoudige oplossing kan zijn om numpy.count_nonzero () :

te gebruiken

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

Laat de naam je niet misleiden, als je het gebruikt met de Boolean net zoals in het voorbeeld, zal het de truc doen.


Antwoord 14

Om het aantal voorvallen te tellen, kunt u 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

Antwoord 15

Probeer dit:

a = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
list(a).count(1)

Antwoord 16

maak gebruik van de methoden die een serie biedt:

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

Antwoord 17

Je kunt woordenboekbegrip gebruiken om een nette oneliner te maken. Meer over woordenboekbegrip kan hier gevonden worden

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

Hiermee wordt een woordenboek gemaakt met de waarden in uw ndarray als sleutels, en de tellingen van de waarden als respectievelijk de waarden voor de sleutels.

Dit zal werken wanneer u voorkomens van een waarde in arrays van dit formaat wilt tellen.


Antwoord 18

Als je geïnteresseerd bent in de snelste uitvoering, weet je van tevoren naar welke waarde(n) je moet zoeken en is je array 1D, of je bent anderszins geïnteresseerd in het resultaat op de afgevlakte array (in welk geval de invoer van de functie moet np.ravel(arr)zijn in plaats van alleen arr), dan is Numba je vriend:

import numba as nb
@nb.jit
def count_nb(arr, value):
    result = 0
    for x in arr:
        if x == value:
            result += 1
    return result

of, voor zeer grote arrays waar parallelisatie nuttig kan zijn:

@nb.jit(parallel=True)
def count_nbp(arr, value):
    result = 0
    for i in nb.prange(arr.size):
        if arr[i] == value:
            result += 1
    return result

Benchmarking deze tegen np.count_nonzero()(die ook een probleem heeft van het maken van een tijdelijke array die kan worden vermeden) en np.unique()-gebaseerde oplossing

import numpy as np
def count_np(arr, value):
    return np.count_nonzero(arr == value)
import numpy as np
def count_np2(arr, value):
    uniques, counts = np.unique(a, return_counts=True)
    counter = dict(zip(uniques, counts))
    return counter[value] if value in counter else 0 

Voor invoer gegenereerd met:

def gen_input(n, a=0, b=100):
    return np.random.randint(a, b, n)

De volgende plots worden verkregen (de tweede rij plots is een zoomlens op de snellere aanpak):


Toont dat Numba-gebaseerde oplossing merkbaar sneller is dan de Numpy-tegenhangers, en voor zeer grote inputs is de parallelle aanpak sneller dan de naïef.


Volledige code beschikbaar hier .


Antwoord 19

Het gaat om nog een stap, maar een flexibelere oplossing die ook zou werken voor 2D-arrays en meer gecompliceerde filters is om een ​​Boolean-masker te maken en vervolgens te gebruiken .sum () op het masker.

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

Antwoord 20

Een algemeen en eenvoudig antwoord zou zijn:

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

wat zou resulteren in deze volledige code als exempliple

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

Nu als Myarray zich in meerdere afmetingen bevindt en wilt u het optreden van een distributie van waarden in lijn (= Pattern Hierna)

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

Antwoord 21

Je hebt hier een speciale array met alleen 1 en 0. Dus een truc is om

. te gebruiken

np.mean(x)

die u het percentage enen in uw array geeft. Gebruik als alternatief

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

geeft u het absolute aantal 1 en 0 in uw array.


Antwoord 22

dict(zip(*numpy.unique(y, return_counts=True)))

Ik heb zojuist de opmerking van Seppo Enarvi hier gekopieerd, die een goed antwoord verdient


Antwoord 23

Dit kan eenvoudig op de volgende manier worden gedaan

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

Antwoord 24

Aangezien je ndarray alleen 0 en 1 bevat,
je kunt sum() gebruiken om het voorkomen van 1s . te krijgen
en len()-sum() om het voorkomen van nullen te krijgen.

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

Antwoord 25

Voor algemene vermeldingen:

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

Zal een telling uitvoeren:

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

en 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]}

Antwoord 26

Als u numpe of een collectiesmodule niet wilt gebruiken, kunt u een woordenboek gebruiken:

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

Resultaat:

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

Natuurlijk kunt u ook een of / else-verklaring gebruiken.
Ik denk dat de tellerfunctie bijna hetzelfde doet, maar dit is meer transparant.


Antwoord 27

Hier heb ik iets, waardoor je het aantal voorkomen van een bepaald aantal kunt tellen:
Volgens uw code

Count_Of_zero = lijst (Y [y == 0]). Tel (0)

Afdrukken (Count_Of_zero)

// Volgens de wedstrijd zijn er Booleaanse waarden en volgens echte waarde wordt het nummer 0 teruggestuurd


Antwoord 28

Als u te maken hebt met zeer grote arrays met behulp van generatoren zou een optie kunnen zijn. Het leuke ding hier dat deze aanpak goed werkt voor zowel arrays als lijsten en je hebt geen extra pakket nodig. Bovendien gebruikt u dat veel geheugen niet.

my_array = np.array([0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1])
sum(1 for val in my_array if val==0)
Out: 8

Antwoord 29

Deze funktion retourneert het aantal voorkomens voor een variabele in een array:

def count(array,variable):
    number = 0
    for i in range(array.shape[0]):
        for j in range(array.shape[1]):
            if array[i,j] == variable:
                number += 1
    return number

ANTWOORD 30

Numpy heeft hiervoor een module. Gewoon een kleine hack. Zet je ingangsarray als bins.

numpy.histogram(y, bins=y)

De uitvoer zijn 2 arrays. Één met de waarden zelf, andere met de bijbehorende frequenties.

Other episodes