วิธีการนับจำนวนองค์ประกอบที่แท้จริงในอาร์เรย์ NumPy


181

ฉันมี 'boolarr' ประเภทบูลีน NumPy 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
ขอบคุณเดวิด พวกเขาดูเรียบร้อย เกี่ยวกับวิธีการที่มีผลรวม (.. ), True เสมอเท่ากับ 1 ใน python (หรืออย่างน้อยในจำนวน numpy) หรือไม่ หากไม่รับประกันฉันจะเพิ่มการตรวจสอบ 'ถ้าเป็นจริง == 1:' ล่วงหน้า เกี่ยวกับ count_nonzero (.. ) โชคไม่ดีที่ดูเหมือนจะไม่ได้ใช้งานในโมดูล numpy ของฉันในรุ่น 1.5.1 แต่ฉันอาจมีโอกาสใช้ในอนาคต
norio

4
@norio เกี่ยวกับbool: ค่าบูลีนจะถือว่าเป็น 1 และ 0 ในการดำเนินการทางคณิตศาสตร์ ดู " ค่าบูลีน " ในเอกสาร Python Standard Library โปรดทราบว่า NumPy boolและ Python boolไม่เหมือนกัน แต่เข้ากันได้ (ดูข้อมูลเพิ่มเติมได้ที่นี่ )
David Alber

1
@norio เกี่ยวกับการnumpy.count_nonzeroไม่ได้อยู่ใน NumPy v1.5.1: คุณพูดถูก ตามประกาศของรุ่นนี้มันถูกเพิ่มเข้ามาใน NumPy v1.6.0
David Alber

25
FWIW numpy.count_nonzeroเร็วกว่าพันเท่าในล่ามภาษาไพ ธ อนอย่างน้อย python -m timeit -s "import numpy as np; bools = np.random.uniform(size=1000) >= 0.5" "np.count_nonzero(bools)"และpython -m timeit -s "import numpy as np; bools = np.random.uniform(size=1000) >= 0.5" "sum(bools)"
chbrown

6
@chrown คุณพูดถูก แต่คุณควรเปรียบเทียบกับnp.sum(bools)แทน! อย่างไรก็ตามnp.count_nonzero(bools)ยังคงเร็วกว่า ~ 12x
mab

30

คำถามนั้นแก้ไขคำถามที่คล้ายกันสำหรับฉันและฉันคิดว่าฉันควรแบ่งปัน:

ในงูหลามดิบคุณสามารถใช้sum()เพื่อนับTrueค่าในlist:

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

แต่สิ่งนี้จะไม่ทำงาน:

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

คุณควร "แผ่" อาร์เรย์ของอาร์เรย์ก่อน น่าเสียดายที่ไม่มีวิธีการ builtin ให้ดูstackoverflow.com/questions/2158395/…
tommy chheng

2
ขอบคุณ Guillaume! ใช้งานได้กับ Pandas Dataframes เช่นกัน
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])

ซึ่งสามารถขยายเป็นมิติข้อมูลได้

ผลลัพธ์ที่ได้คือ:

คาดการณ์:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.