Python Bins/Numpy数字化-从中点创建Bin



我想创建一个函数,将[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)

我希望中间是最小的垃圾箱,但会得到意想不到的结果。。。

参考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))

任何建议/建议,不胜感激!

您正经历浮点运算的不准确。要查看它与您的特定功能无关,请尝试例如

>>> 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玩得有多好。当然不会很快。

最新更新