Cách đếm số phần tử thực trong mảng bool NumPy


180

Tôi có một mảng NumPy 'boolarr' thuộc loại boolean. Tôi muốn đếm số phần tử có giá trị là True. Có một thói quen NumPy hoặc Python dành riêng cho nhiệm vụ này không? Hoặc, tôi có cần lặp lại các yếu tố trong kịch bản của mình không?


Câu trả lời:


261

Bạn có nhiều lựa chọn. Hai lựa chọn như sau.

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

Đây là một ví dụ:

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

Tất nhiên, đó là một boolcâu trả lời cụ thể. Tổng quát hơn, bạn có thể sử dụng numpy.count_nonzero.

>>> np.count_nonzero(boolarr)
5

2
Cảm ơn, David. Họ trông gọn gàng. Về phương thức với sum (..), True có luôn bằng 1 trong python (hoặc ít nhất là trong numpy) không? Nếu nó không được đảm bảo, tôi sẽ thêm một kiểm tra, 'nếu True == 1:' trước. Về Count_nonzero (..), thật không may, có vẻ như nó không được triển khai trong mô-đun numpy của tôi tại phiên bản 1.5.1, nhưng tôi có thể có cơ hội sử dụng nó trong tương lai.
norio

4
@norio Về bool: các giá trị boolean được coi là 1 và 0 trong các phép toán số học. Xem " Giá trị Boolean " trong tài liệu Thư viện chuẩn Python. Lưu ý rằng NumPy boolvà Python boolkhông giống nhau, nhưng chúng tương thích (xem tại đây để biết thêm thông tin).
David Alber

1
@norio Về việc numpy.count_nonzerokhông tham gia NumPy v1.5.1: bạn đã đúng. Theo thông báo phát hành này , nó đã được thêm vào NumPy v1.6.0.
David Alber

25
FWIW, numpy.count_nonzeronhanh hơn khoảng một nghìn lần, trong trình thông dịch Python của tôi, ít nhất. python -m timeit -s "import numpy as np; bools = np.random.uniform(size=1000) >= 0.5" "np.count_nonzero(bools)"so vớipython -m timeit -s "import numpy as np; bools = np.random.uniform(size=1000) >= 0.5" "sum(bools)"
chbrown

6
@chbrown bạn nói đúng. Nhưng bạn nên so sánh để np.sum(bools)thay thế! Tuy nhiên, np.count_nonzero(bools)vẫn nhanh hơn ~ 12 lần.
mab

29

Câu hỏi đó đã giải quyết một câu hỏi khá giống tôi và tôi nghĩ mình nên chia sẻ:

Trong python thô, bạn có thể sử dụng sum()để đếm Truecác giá trị trong list:

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

Nhưng điều này sẽ không hoạt động:

>>> sum([[False, False, True], [True, False, True]])
TypeError...

Bạn nên "làm phẳng" mảng của mảng trước. thật không may, không có phương thức dựng sẵn nào, hãy xem stackoverflow.com/questions/2158395/
trộm

2
Cảm ơn Guillaume! Làm việc với các tệp dữ liệu Pandas là tốt.
JJFord3

4

Về mặt so sánh hai mảng numpy và đếm số lượng trận đấu (ví dụ: dự đoán lớp chính xác trong học máy), tôi thấy ví dụ dưới đây cho hai chiều hữu ích:

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

có thể được mở rộng đến kích thước D.

Kết quả là:

Sự dự đoán:

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

Mục tiêu:

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

Đếm dự đoán đúng cho D = 1: 1

Đếm dự đoán đúng cho D = 2: 2

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.