【问题标题】:Quickly assign an array to n bins with equal length快速将一个数组分配给 n 个长度相等的 bin
【发布时间】:2017-07-21 15:12:52
【问题描述】:

例如,我有一个数组流,其数字范围从 0.010.0(含)。

我想快速将arr 中的数字分配给5 等长的箱子。

等长是指 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。

【问题讨论】:

  • 我想你可能正在寻找numpy.digitize
  • min 是 0。max 正好是 10。 digitize 允许长度不均匀的 bin,可能会更慢。这是相等的长度。
  • pandas.cut怎么样
  • @jeremycg 我试图阅读 pandas.cut 的源代码。它似乎事先调整了最大值,比如将最大值乘以 1.001。这会在分箱中产生一些小错误,但之后不需要剪辑。
  • 你的逻辑没问题,只是最后少了一行:norm_data[norm_data >= n_bins] = n_bins -1,相当于贴出来的解决方案。

标签: python numpy binning discretization


【解决方案1】:

穷人的解决方案”可能是计算数组norm_datanbins-1 之间的minimum

norm_data = np.minimum(norm_data,nbins-1)

所以所有5s(及以上)都将转换为4s。请注意,当然在这里您不会进行适当的范围检查(120.0 也将在 bin 4 中结束)。

【讨论】:

    【解决方案2】:

    如果 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 和 n_bins - 1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 2011-02-09
    • 2021-10-30
    • 2023-03-23
    相关资源
    最近更新 更多