Как посчитать количество истинных элементов в массиве NumPy bool

181

У меня есть массив NumPy 'boolarr' логического типа. Я хочу посчитать количество элементов, значения которых True. Есть ли для этой задачи подпрограмма NumPy или Python? Или мне нужно перебрать элементы в моем скрипте?

Норио
источник
4
Для панд: stackoverflow.com/questions/26053849/…
частное

Ответы:

262

У вас есть несколько вариантов. Два варианта следующие.

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

Вот пример:

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

Конечно, это конкретный boolответ. В целом, вы можете использовать numpy.count_nonzero.

>>> np.count_nonzero(boolarr)
5
Дэвид Альбер
источник
2
Спасибо, Дэвид. Они выглядят аккуратно. Что касается метода с sum (..), всегда ли True равен 1 в python (или хотя бы в numpy)? Если это не гарантировано, я добавлю проверку, если «True == 1:» заранее. Что касается count_nonzero (..), к сожалению, он не реализован в моем numpy модуле в версии 1.5.1, но я могу использовать его в будущем.
Норио
4
@norio Относительно bool: логические значения обрабатываются как 1 и 0 в арифметических операциях. Смотрите " Булевы значения " в документации по стандартной библиотеке Python. Обратите внимание, что NumPy boolи Python boolне совпадают, но они совместимы (см. Здесь для получения дополнительной информации).
Дэвид Альбер
1
@norio Что касается numpy.count_nonzeroотсутствия в NumPy v1.5.1: вы правы. Согласно этому сообщению , оно было добавлено в NumPy v1.6.0.
Дэвид Альбер
25
FWIW, numpy.count_nonzeroпримерно в тысячу раз быстрее, по крайней мере, в моем интерпретаторе Python. 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 ты прав. Но вы должны сравнить np.sum(bools)вместо этого! Тем не менее, np.count_nonzero(bools)все еще ~ 12 раз быстрее.
МАБ
30

Этот вопрос решил для меня очень похожий вопрос, и я решил поделиться:

В сыром Python вы можете использовать sum()для подсчета Trueзначений в list:

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

Но это не сработает:

>>> sum([[False, False, True], [True, False, True]])
TypeError...
Гийом Жандр
источник
Вы должны сначала сплющить массив массивов. к сожалению, нет никакого способа встроенного см stackoverflow.com/questions/2158395/...
автоматчики chheng
2
Спасибо, Гийом! Работает также с датафреймами Pandas.
JJFord3
5

С точки зрения сравнения двух числовых массивов и подсчета количества совпадений (например, правильное предсказание классов в машинном обучении) я нашел следующий пример для двух измерений полезным:

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

который может быть расширен до размеров D.

Результаты:

Прогноз:

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

Цель:

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

Подсчет правильного прогноза для D = 1: 1

Подсчет правильного прогноза для D = 2: 2

salehinejad
источник