So zählen Sie die Anzahl der wahren Elemente in einem NumPy-Bool-Array

179

Ich habe ein NumPy-Array 'boolarr' vom booleschen Typ. Ich möchte die Anzahl der Elemente zählen, deren Werte sind True. Gibt es eine NumPy- oder Python-Routine für diese Aufgabe? Oder muss ich die Elemente in meinem Skript durchlaufen?

norio
quelle

Antworten:

261

Sie haben mehrere Möglichkeiten. Zwei Optionen sind die folgenden.

numpy.sum(boolarr)
numpy.count_nonzero(boolarr)

Hier ist ein Beispiel:

>>> import numpy as np
>>> boolarr = np.array([[0, 0, 1], [1, 0, 1], [1, 0, 1]], dtype=np.bool)
>>> boolarr
array([[False, False,  True],
       [ True, False,  True],
       [ True, False,  True]], dtype=bool)

>>> np.sum(boolarr)
5

Das ist natürlich eine boolspezifische Antwort. Allgemeiner können Sie verwenden numpy.count_nonzero.

>>> np.count_nonzero(boolarr)
5
David Alber
quelle
2
Danke, David. Sie sehen ordentlich aus. Ist True in Bezug auf die Methode mit sum (..) in Python immer gleich 1 (oder zumindest in numpy)? Wenn dies nicht garantiert ist, füge ich vorher einen Check hinzu, 'if True == 1:'. Über count_nonzero (..) scheint es leider nicht in meinem numpy-Modul in Version 1.5.1 implementiert zu sein, aber ich habe möglicherweise die Möglichkeit, es in Zukunft zu verwenden.
Norio
4
@norio Betreff bool: Boolesche Werte werden in arithmetischen Operationen als 1 und 0 behandelt. Siehe " Boolesche Werte " in der Dokumentation zur Python-Standardbibliothek. Beachten Sie, dass NumPy's boolund Python boolnicht identisch sind, aber kompatibel (siehe hier für weitere Informationen).
David Alber
1
@norio In Bezug auf numpy.count_nonzeronicht in NumPy v1.5.1: Sie haben Recht. Laut dieser Release-Ankündigung wurde es in NumPy v1.6.0 hinzugefügt.
David Alber
25
FWIW numpy.count_nonzeroist zumindest in meinem Python-Interpreter ungefähr tausendmal schneller. python -m timeit -s "import numpy as np; bools = np.random.uniform(size=1000) >= 0.5" "np.count_nonzero(bools)"vs.python -m timeit -s "import numpy as np; bools = np.random.uniform(size=1000) >= 0.5" "sum(bools)"
chbrown
6
@chbrown du hast recht. Aber du solltest np.sum(bools)stattdessen mit vergleichen ! Ist np.count_nonzero(bools)aber immer noch ~ 12x schneller.
Mab
29

Diese Frage löste eine ganz ähnliche Frage für mich und ich dachte, ich sollte teilen:

In roher Python können Sie verwenden , sum()zählen TrueWerte in a list:

>>> sum([True,True,True,False,False])
3

Aber das wird nicht funktionieren:

>>> sum([[False, False, True], [True, False, True]])
TypeError...
Guillaume Gendre
quelle
Sie sollten zuerst das Array von Arrays "reduzieren". Leider gibt es keine eingebaute Methode, siehe stackoverflow.com/questions/2158395/…
Tommy Chheng
2
Danke Guillaume! Funktioniert auch mit Pandas-Datenrahmen.
JJFord3
4

In Bezug auf den Vergleich von zwei Numpy-Arrays und das Zählen der Anzahl von Übereinstimmungen (z. B. korrekte Klassenvorhersage beim maschinellen Lernen) fand ich das folgende Beispiel für zwei Dimensionen nützlich:

import numpy as np
result = np.random.randint(3,size=(5,2)) # 5x2 random integer array
target = np.random.randint(3,size=(5,2)) # 5x2 random integer array

res = np.equal(result,target)
print result
print target
print np.sum(res[:,0])
print np.sum(res[:,1])

die auf D-Dimensionen erweitert werden kann.

Die Ergebnisse sind:

Prognose:

[[1 2]
 [2 0]
 [2 0]
 [1 2]
 [1 2]]

Ziel:

[[0 1]
 [1 0]
 [2 0]
 [0 0]
 [2 1]]

Anzahl der korrekten Vorhersagen für D = 1: 1

Anzahl der korrekten Vorhersagen für D = 2: 2

salehinejad
quelle
3

Wenn Sie eine Zählung pro Zeile durchführen möchten, geben Sie Folgendes axis=1an sum:

boolarr
# array([[False, False,  True],
#        [ True, False,  True],
#        [ True, False,  True]], dtype=bool)

boolarr.sum(axis=1)
# array([1, 2, 2])

Ebenso mit np.count_nonzero:

np.count_nonzero(boolarr, axis=1)
# array([1, 2, 2])
cs95
quelle