[英]Merging bins in numpy array
我有一个直方图保存在一个数组中,第一列中最右边的 bin 和第二列中的相应频率。 例如:
array([[1.00000000e+00, 9.76765797e-02],
[2.00000000e+00, 3.26260189e-02],
[3.00000000e+00, 2.27720518e-03],
[4.00000000e+00, 1.61188858e-01],
[5.00000000e+00, 1.23496687e-01],
[6.00000000e+00, 2.04377586e-01],
[7.00000000e+00, 7.47678209e-02],
[8.00000000e+00, 4.67140951e-02],
[9.00000000e+00, 1.31659099e-01],
[1.00000000e+01, 1.25216050e-01]])
重新排列此直方图的最快方法是什么,例如将 bin 大小设为2.5
?
结果数组的第一列应为2.5,5.0,7.5,10.0
,区间[0,2.5],(2.5,5.0],(5.0,7.5],(5.0,10.]
的频率值的总和为第二列。
我试图找到一种紧凑的方法来进行这种转换,但找不到它。
编辑:正如 Jakob Stark 让我注意到的那样,一般来说不可能重新排列直方图。 但是,可以合并 bin。 例如,将 bin 大小增加一倍或三倍。 如何以紧凑的方式做到这一点?
我已经更新了问题的标题以反映编辑。
您不能重新排列直方图。 如果您在直方图中填充数据,则会丢失信息(实际上这通常是您想要直方图的原因)。 除非您仍然拥有原始数据,否则无法获得具有不同分箱的直方图。
如果您有原始数据,您当然可以制作一个新的直方图,其中包含所需的分箱。
编辑您可以合并垃圾箱。 因此,只要您的新 bin 可以通过合并的 bin 表示(例如两倍的 bin 大小),您就可以将每个贡献 bin 的 wheights 添加到合并的 bin。
编辑例如,您可以使用将 bin 大小加倍
n = 2 # merge 2 bins
bins, weights = old_hist[:,0], old_hist[:,1]
bins = bins.reshape((-1,n))[:,0]
weights = np.sum(weights.reshape((-1,n)), axis=1)
new_hist = np.column_stack((bins,weights))
正如@Jakob Stark 指出的那样,只要您的新垃圾箱大小是旧垃圾箱的倍数,您就可以重新装箱; 这使您可以干净地合并垃圾箱。
下面是一个示例,说明如何使用不同的 bin 大小对数据进行 bin:
import numpy as np
arr = np.array(
[
[1.00000000e00, 9.76765797e-02],
[2.00000000e00, 3.26260189e-02],
[3.00000000e00, 2.27720518e-03],
[4.00000000e00, 1.61188858e-01],
[5.00000000e00, 1.23496687e-01],
[6.00000000e00, 2.04377586e-01],
[7.00000000e00, 7.47678209e-02],
[8.00000000e00, 4.67140951e-02],
[9.00000000e00, 1.31659099e-01],
[1.00000000e01, 1.25216050e-01],
]
)
rightmost = arr[-1][0]
bin_sizes = [2, 3, 5]
for size in bin_sizes:
result = []
for i in range(0, int(rightmost), size):
bound = min(rightmost, i + size)
freq = arr[i : i + size, 1].sum()
result.append((bound, freq))
print(np.array(result), end="\n\n")
这将产生以下 output:
[[ 2. 0.1303026 ]
[ 4. 0.16346606]
[ 6. 0.32787427]
[ 8. 0.12148192]
[10. 0.25687515]]
[[ 3. 0.1325798 ]
[ 6. 0.48906313]
[ 9. 0.25314101]
[10. 0.12521605]]
[[ 5. 0.41726535]
[10. 0.58273465]]
编辑:
作为单个列表理解:
n = arr[-1, 0]
bin_size = 2
rebinned = np.array(
[
a.sum(axis=0) - (a[:-1, 0].sum(axis=0), 0)
for a in np.array_split(arr, n / bin_size)
]
)
最后,我想出了这个。 不过,恐怕效率不是很高:
data=array([[1.00000000e+00, 9.76765797e-02],
[2.00000000e+00, 3.26260189e-02],
[3.00000000e+00, 2.27720518e-03],
[4.00000000e+00, 1.61188858e-01],
[5.00000000e+00, 1.23496687e-01],
[6.00000000e+00, 2.04377586e-01],
[7.00000000e+00, 7.47678209e-02],
[8.00000000e+00, 4.67140951e-02],
[9.00000000e+00, 1.31659099e-01],
[1.00000000e+01, 1.25216050e-01]])
bin_size=2.
x=data[:,0]
y=data[:,1]
nbins=max(x)/bin_size
x_merge=asarray([max(a) for a in array_split(x,nbins)])
y_merge=asarray([sum(a) for a in array_split(y,nbins)])
out_array=column_stack((x_merge,y_merge))
仍然对更有效/更紧凑的方法感兴趣。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.