为每个数据点分配直方图bin

时间:2015-07-21 16:29:29

标签: python arrays numpy histogram

我有一个数组days=[1,4,5,2,7,2,7,8,3,10]。我使用a,b=numpy.histogram(days,bins=5)从这个数组创建了一个直方图。 a和b的值是

a=[3,2,1,3,1]
b=[1., 2.8, 4.6, 6.4, 8.2, 10.]

我想要的是创建另一个与days大小相同的数组标签,但它应该告诉我days中的哪个bin数据属于。在这种情况下,输出应为

label=[1,2,3,1,4,1,4,4,2,5]

这里意味着共有5个箱子。 days [0] = 1属于label [0] = 1st bin days [1] = 4属于label [1] = 2nd bin,依此类推。我可以使用for循环并迭代每个元素的天数比较它们与bin间隔但我有大数据集说天数将接近4000点,并将有20个箱。因此,如果我迭代所有数据并与每个bin进行比较,那么将会有20个比较使代码混乱。有没有办法减少这种混乱并使整个过程自动化

1 个答案:

答案 0 :(得分:2)

np.digitize可以生成标签:

In [68]: a, b = np.histogram(days,bins=5)

In [69]: np.digitize(days, bins=b)
Out[69]: array([1, 2, 3, 1, 4, 1, 4, 4, 2, 6])

请注意,您无需先拨打np.histogram;这只是为了使np.digitize使用与np.histogram生成的相同的bin。你也可以用:

生成垃圾箱
In [71]: np.linspace(1, 10, 6)
Out[71]: array([  1. ,   2.8,   4.6,   6.4,   8.2,  10. ])

或者更一般地说,

In [76]: np.linspace(min(days), max(days), 6)
Out[76]: array([  1. ,   2.8,   4.6,   6.4,   8.2,  10. ])

默认情况下,np.digitize使用半开边距,不包括右边边。如果right=True,则包含右边框边缘,但左边不是:

In [72]: np.digitize(days, bins=b, right=True)
Out[72]: array([0, 2, 3, 1, 4, 1, 4, 4, 2, 5])

要获得您发布的确切输出,您可以稍微扩展最右边的bin边缘:

In [80]: np.digitize(days, bins=np.linspace(1, np.nextafter(10,np.inf), 6))
Out[80]: array([1, 2, 3, 1, 4, 1, 4, 4, 2, 5])

虽然bins=np.linspace(1, 11, 6)也适用于此示例,但最好以尽可能小的数量增加10,以便尽可能少地更改其他bin边缘。 np.nextafter(10, np.inf)np.inf的方向上返回10后可表示为浮点数的下一个数字。

In [82]: np.nextafter(10,np.inf)
Out[82]: 10.000000000000002