繁体   English   中英

合并 numpy 阵列中的 bin

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM