【问题标题】:Python Bins / Numpy Digitize - Creating bins from midpointPython Bins / Numpy Digitize - 从中​​点创建 bin
【发布时间】:2017-02-05 22:19:04
【问题描述】:

我想创建一个函数,将 [0,1] 范围内的数字放入 bin 中,其中 n 是 bin 的数量,边界是相对于中点定义的。

0.0 >= Bin 1 <= 0.2 <- outer left bin
0.2 > Bin 2 <= 0.4
0.4 > Bin 3 < 0.6  <- middle bin    
0.6 >= Bin 4 < 0.8
0.8 >= Bin 5 <= 1 <- outer right bin

我认为我可以做到以下几点:

def fractile(x, n):
    bins = np.linspace(0.0, 1.0, n+1)
    return np.where(x > 0.5,
                    np.digitize(x, bins, right=False),
                    np.digitize(x, bins, right=True))

x = pd.DataFrame(np.linspace(0.05, 0.95, 19))
f = fractile(x, 10)

n = 10 的结果:

array([[ 1],
   [ 1],
   [ 2],
   [ 2],
   [ 3],
   [ 3],
   [ 4],
   [ 4],
   [ 5],
   [ 5],
   [ 6],
   [ 6],
   [ 7],
   [ 7],
   [ 8],
   [ 8],
   [ 9],
   [10],
   [10]], dtype=int64)

我希望中间是最小的 bin,但会得到意想不到的结果......

参考 Pauls 的回答,可以在评估之前将函数修改为舍入,从而缓解浮点算术问题,但看起来很难看:

def fractile(x, n):
    x = np.round(x, 15)
    bins = np.round(np.linspace(0.0, 1.0, n+1), 15)
    return np.where(x > 0.5,
                    np.digitize(x, bins, right=False),
                    np.digitize(x, bins, right=True))

任何建议/指针表示赞赏!

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    您只是在体验浮点运算的不准确性。要查看它与您的特定功能无关,请尝试例如

    >>> np.digitize(np.linspace(0.05,0.95,19), np.linspace(0,1,11))
    array([ 1,  2,  2,  3,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,
       10, 10])
    

    或直接

    >>> np.linspace(0.05,0.95,19) == np.linspace(0,1,21)[1:-1]
    array([ True,  True, False,  True,  True, False, False, False, False,
       False, False, False,  True, False,  True, False, False,  True, False], dtype=bool)                                                             
    

    如果您需要精确的边界,请尽可能使用整数。如果没有,则有分数模块。不过,不确定它与 numpy 的表现如何。肯定不会很快。

    【讨论】:

    • 有趣又烦人!尝试在 fractile() 函数内舍入到可接受的精度,但并不理想。编辑问题以反映。
    猜你喜欢
    • 1970-01-01
    • 2018-10-31
    • 2017-01-11
    • 2021-04-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    相关资源
    最近更新 更多