2

我想制作一个直方图,其中数据存在于周期性空间中,但一个 bin 与边界相交,也就是说,最左边和最右边的 bin 应该是相同的。

例如,如果我的角度数据范围从0360,并且想要制作NSEWbin ,则该Nbin 应该包含来自0to45 from 315to的数据360。我不能做类似的事情,np.histogram(data, bins=[315,45,135,225,315])因为bins must increase monotonically

当然,我可以通过“旋转”它来预处理我的数据,data[data>bins.max()] -= 360但这似乎是一种黑客行为,我想知道是否有更清洁的方法。

4

2 回答 2

2

你可以这样做:

a = 360 * rand(5000)
look_up = np.array([0, 1, 1, 2, 2, 3, 3, 0])
ind = (a//45).astype(np.int8)
out = np.bincount(look_up[ind])

基本上,您创建了一个查找数组,其条目数是您想要的 bin 的两倍(在您的情况下)。你比整数除以你想要索引到查找数组的 bin 间距的一半(我们使用 numpy 索引魔法来完成这项工作)。np.bincountthan 返回每个 bin 被命中的次数,也就是你想要的直方图。

你也可以用histogram一些切片技巧来做到这一点

a = 360 * rand(50000)

h, be = np.histogram(a, bins=8, range=(0, 360))  # 2x bins

h_p = np.sum(np.r_[h[-1], h[:-1]].reshape(-1, 2), axis=1) # rotate and sum
be_p = np.r_[np.r_[be[-2], be[:-2]][::2], be[-2]]         # rotate and skip

附带说明一下,换档可能会更快

data_shifted = np.mod(data + 45, 360.0)
于 2013-08-25T05:02:30.230 回答
2

您可以使用np.digitize

>>> a=np.random.randint(0,360,5000)
>>> ind=np.digitize(a,[45,135,225,315,360])
>>> np.bincount(ind)
array([ 616, 1246, 1268, 1249,  621])
# 0-45, 45-135, 135-225, 225-315, 315-360

>>> bins=np.bincount(ind)
>>> count=bins[:-1]
>>> count[0]+=bins[-1]
>>> count
array([1237, 1246, 1268, 1249])

仍然是一种黑客行为。

于 2013-08-24T23:10:34.700 回答