具有周期性边界条件的数据的直方图

时间:2013-08-24 22:55:04

标签: python numpy matplotlib

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

例如,如果我的角度数据范围为0360,并且想要NSEW bin,N bin应包含045 315360的数据。由于np.histogram(data, bins=[315,45,135,225,315]),我无法执行bins must increase monotonically之类的操作。

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

2 个答案:

答案 0 :(得分: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])

仍然是一种黑客攻击。

答案 1 :(得分: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间距的一半(并且我们使用numpy索引魔法使这个工作)。np.bincount比返回每个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)