numpy.histogram () ทำงานอย่างไร?


121

ในขณะที่อ่านบน numpy numpy.histogram()ผมพบฟังก์ชั่น

มีไว้ทำอะไรและทำงานอย่างไร? ในเอกสารพวกเขากล่าวถึงถังขยะ : พวกเขาคืออะไร?

บาง googling นำฉันไปที่ความหมายของ Histograms ทั่วไป ฉันเข้าใจ. แต่น่าเสียดายที่ฉันไม่สามารถเชื่อมโยงความรู้นี้กับตัวอย่างที่ให้ไว้ในเอกสารได้

คำตอบ:


167

ถังขยะคือช่วงที่แสดงถึงความกว้างของแท่งเดียวของฮิสโตแกรมตามแกน X คุณยังสามารถเรียกช่วงเวลานี้ได้ (Wikipedia ให้คำจำกัดความอย่างเป็นทางการมากขึ้นว่าเป็น "หมวดหมู่ที่ไม่ปะติดปะต่อ")

histogramฟังก์ชันNumpy ไม่ได้วาดฮิสโตแกรม แต่จะคำนวณการเกิดขึ้นของข้อมูลอินพุตที่อยู่ในแต่ละถังซึ่งจะกำหนดพื้นที่ (ไม่จำเป็นต้องเป็นความสูงหากถังขยะมีความกว้างไม่เท่ากัน) ของแต่ละแท่ง

ในตัวอย่างนี้:

 np.histogram([1, 2, 1], bins=[0, 1, 2, 3])

มี 3 ถังสำหรับค่าตั้งแต่ 0 ถึง 1 (ไม่รวม 1), 1 ถึง 2 (ไม่รวม 2) และ 2 ถึง 3 (รวม 3) ตามลำดับ วิธีที่ Numpy กำหนดถังขยะเหล่านี้หากให้รายการตัวคั่น ( [0, 1, 2, 3]) ในตัวอย่างนี้แม้ว่าจะส่งคืนถังขยะในผลลัพธ์ด้วยก็ตามเนื่องจากสามารถเลือกถังขยะเหล่านี้ได้โดยอัตโนมัติจากอินพุตหากไม่มีการระบุ bins=5ตัวอย่างเช่นหากจะใช้ 5 ถังขยะที่มีความกว้างเท่ากันกระจายระหว่างค่าอินพุตต่ำสุดและค่าอินพุตสูงสุด

ค่าที่ป้อนคือ 1, 2 และ 1 ดังนั้น bin "1 ถึง 2" จึงมีสองเหตุการณ์ (สอง1ค่า) และ bin "2 ถึง 3" มีหนึ่งรายการ (the 2) ผลการเหล่านี้อยู่ในรายการแรกใน tuple array([0, 2, 1])กลับมาว่า:

เนื่องจากถังขยะมีความกว้างเท่ากันคุณจึงใช้จำนวนครั้งที่เกิดขึ้นสำหรับความสูงของแต่ละแท่งได้ เมื่อวาดคุณจะมี:

  • แถบความสูง 0 สำหรับ range / bin [0,1] บนแกน X
  • แถบความสูง 2 สำหรับ range / bin [1,2],
  • แถบความสูง 1 สำหรับ range / bin [2,3]

คุณสามารถพล็อตสิ่งนี้ได้โดยตรงด้วย Matplotlib ( histฟังก์ชันของมันยังส่งคืนถังขยะและค่า):

>>> import matplotlib.pyplot as plt
>>> plt.hist([1, 2, 1], bins=[0, 1, 2, 3])
(array([0, 2, 1]), array([0, 1, 2, 3]), <a list of 3 Patch objects>)
>>> plt.show()

ใส่คำอธิบายภาพที่นี่


8
คุณอาจสนใจคำตอบนี้หากคุณต้องการพล็อต Matplotlib ยังสามารถคำนวณได้โดยตรง ดูตัวอย่างที่นี่และที่นี่
Bruno

ในชุดข้อมูลดอกไอริสจำนวน bin_edges = np.histogram (iris_setosa ['Petal_length'], bins = 10, ความหนาแน่น = จริง) ให้จำนวนของฉันเป็นค่าลอยตามตัวอย่างที่คุณให้ไว้ว่าจะนับได้อย่างไร ค่าลอย?
Dipen Gajjar

คำตอบที่ดีที่สุดควรคำนึงถึงว่าค่าจำนวนมากที่มีนัยสำคัญเหนือขอบขวาสุดจะถูกละเว้น เพิ่มค่าเหนือขอบตะแกรงไปยังถังสุดท้ายหรือเปลี่ยนbinsค่าที่สร้างขึ้นด้วยตนเองล่าสุดเป็นค่าสูงสุดในอาร์เรย์
A.Ametov

@DipenGajjar ถ้าคุณเว้น "ความหนาแน่น = จริง" คุณจะไม่เห็นสิ่งนั้น คีย์เวิร์ดความหนาแน่นจะให้ฮิสโตแกรม "ปกติ" ซึ่งแสดงฟังก์ชันความหนาแน่นของความน่าจะเป็น คุณสามารถอ่านเกี่ยวกับเรื่องนี้ที่นี่
BUFU

67
import numpy as np    
hist, bin_edges = np.histogram([1, 1, 2, 2, 2, 2, 3], bins = range(5))

ด้านล่างhistระบุว่ามี 0 รายการใน bin # 0, 2 ใน bin # 1, 4 ใน bin # 3, 1 ใน bin # 4

print(hist)
# array([0, 2, 4, 1])   

bin_edges ระบุว่า bin # 0 คือช่วงเวลา [0,1), bin # 1 คือ [1,2), ... , bin # 3 คือ [3,4)

print (bin_edges)
# array([0, 1, 2, 3, 4]))  

เล่นด้วยรหัสด้านบนเปลี่ยนอินพุตnp.histogramและดูว่ามันทำงานอย่างไร


แต่ภาพมีค่าหนึ่งพันคำ:

import matplotlib.pyplot as plt
plt.bar(bin_edges[:-1], hist, width = 1)
plt.xlim(min(bin_edges), max(bin_edges))
plt.show()   

ใส่คำอธิบายภาพที่นี่


4
ฉันคิดว่านี่น่าจะแม่นยำกว่า: plt.bar(bin_edges[:-1], hist, width=1)และplt.xlim(min(bin_edges), max(bin_edges))เพื่อให้แท่งพอดีกับความกว้างที่คาดไว้ (มิฉะนั้นอาจมีเพียงถังขนาดเล็กที่ไม่มีค่าอยู่ระหว่าง)
Bruno

เป็นไปได้ไหมที่จะใช้ "hist" ที่ได้รับในรูปแบบ numpy ด้านบนในฟังก์ชัน "plt.hist (... )" เนื่องจากในวิธีการแบบแท่งคุณระบุเป็น "y" ในขณะที่ใน
Hist

7

สิ่งที่มีประโยชน์อีกอย่างที่ต้องทำnumpy.histogramคือการพล็อตเอาต์พุตเป็นพิกัด x และ y บนกราฟเส้น ตัวอย่างเช่น:

arr = np.random.randint(1, 51, 500)
y, x = np.histogram(arr, bins=np.arange(51))
fig, ax = plt.subplots()
ax.plot(x[:-1], y)
fig.show()

ใส่คำอธิบายภาพที่นี่

นี่อาจเป็นวิธีที่มีประโยชน์ในการแสดงภาพฮิสโตแกรมที่คุณต้องการระดับความละเอียดที่สูงขึ้นโดยไม่ต้องมีแถบทุกที่ มีประโยชน์มากในฮิสโทแกรมของภาพสำหรับการระบุค่าพิกเซลที่รุนแรง


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