快速将数组分配给长度相等的 n 个 bin
Quickly assign an array to n bins with equal length
例如,我有一个数组流,其数字范围从 0.0
到 10.0
(含)。
我想将arr
中的数字快速分配给5
个等长的bin。
等长是指 bin 间隔为 [0.0, 2.0), [2.0, 4.0), [4.0, 6.0), [6.0, 8.0), [8.0, 10.0]
。
问题是最后一个间隔与其他间隔不同。
测试:
import numpy as np
# Things we know and can pre-calculate
n_bins = 5
minimal = 0.0
maximal = 10.0
reciprocal_bin_length = n_bins / (maximal - minimal)
# Let's say the stream gives 1001 numbers every time.
data = np.arange(1001)/100
norm_data = (data - minimal) * reciprocal_bin_length
norm_data = norm_data.astype(int)
print(norm_data.max())
print(norm_data.min())
结果:
5
0
bin 索引应该是 0、1、2、3 或 4,而不是 5。
“穷人的解决方案”可能是计算数组 norm_data
和 nbins-1
之间的 minimum:
norm_data = np.minimum(norm_data,nbins-1)
因此所有 5
(及以上)都将转换为 4
。请注意,当然在这里您不会进行适当的范围检查(120.0
也将在 bin 4 中结束)。
如果可以接受0.1%的误差,下面的会快一点。
不确定这是否适用于浮点舍入。
import numpy as np
# Things we know and can pre-calculate
n_bins = 5
minimal = 0.0
maximal = 10.0
approx = 1.001 # <-- this is new
reciprocal_bin_length = n_bins / (maximal*approx - minimal)
# Let's say the stream gives 1001 numbers every time.
data = np.arange(1001)/100
# can use numexpr for speed.
norm_data = (data - minimal) * reciprocal_bin_length
norm_data = norm_data.astype(int)
print(norm_data.max())
print(norm_data.min())
例如,我有一个数组流,其数字范围从 0.0
到 10.0
(含)。
我想将arr
中的数字快速分配给5
个等长的bin。
等长是指 bin 间隔为 [0.0, 2.0), [2.0, 4.0), [4.0, 6.0), [6.0, 8.0), [8.0, 10.0]
。
问题是最后一个间隔与其他间隔不同。
测试:
import numpy as np
# Things we know and can pre-calculate
n_bins = 5
minimal = 0.0
maximal = 10.0
reciprocal_bin_length = n_bins / (maximal - minimal)
# Let's say the stream gives 1001 numbers every time.
data = np.arange(1001)/100
norm_data = (data - minimal) * reciprocal_bin_length
norm_data = norm_data.astype(int)
print(norm_data.max())
print(norm_data.min())
结果:
5
0
bin 索引应该是 0、1、2、3 或 4,而不是 5。
“穷人的解决方案”可能是计算数组 norm_data
和 nbins-1
之间的 minimum:
norm_data = np.minimum(norm_data,nbins-1)
因此所有 5
(及以上)都将转换为 4
。请注意,当然在这里您不会进行适当的范围检查(120.0
也将在 bin 4 中结束)。
如果可以接受0.1%的误差,下面的会快一点。 不确定这是否适用于浮点舍入。
import numpy as np
# Things we know and can pre-calculate
n_bins = 5
minimal = 0.0
maximal = 10.0
approx = 1.001 # <-- this is new
reciprocal_bin_length = n_bins / (maximal*approx - minimal)
# Let's say the stream gives 1001 numbers every time.
data = np.arange(1001)/100
# can use numexpr for speed.
norm_data = (data - minimal) * reciprocal_bin_length
norm_data = norm_data.astype(int)
print(norm_data.max())
print(norm_data.min())