你在-0.
和+0.
之间遇到的问题是浮点数应该如何行为的规范(IEEE754)的一部分。在某些情况下,需要区分这两个值。例如,请参阅链接到around
文档中的文档。
值得注意的是,两个零应该被视为相等,因此
np.array(-0.)==np.array(+0.)
换句话说,我认为问题更可能出在你的唯一性比较上面。例如:
a = np.array([-1., -0., 0., 1.])
np.unique(a)
如果您想保留数字的浮点数形式,但所有的零都相同,可以使用:
x = np.linspace(-2, 2, 6)
y = x.round()
y[y==0.] = 0.
y += 0.
请注意,您需要进行这样一点额外的工作,因为您试图避免浮点数规范。
还要注意,这并不是由于四舍五入误差导致的。例如,
np.fix(np.array(-.4)).tostring().encode('hex')
np.fix(np.array(-0.)).tostring().encode('hex')
也就是说,最终的数字完全相同,但是
np.fix(np.array(0.)).tostring().encode('hex')
不同。这就是你的方法无法工作的原因,因为它在比较数字的二进制表示时有所不同,这两个零的二进制表示是不同的。因此,我认为问题更多地是比较方法而不是比较浮点数唯一性的一般想法。
各种方法的快速timeit测试:
data0 = np.fix(4*np.random.rand(1000000,)-2)
N = 100
data = np.array(data0)
print timeit.timeit("data += 0.", setup="from __main__ import np, data", number=N)
data = np.array(data0)
print timeit.timeit("data[data==0.] = 0.", setup="from __main__ import np, data", number=N)
data = np.array(data0)
print timeit.timeit("data.astype(np.int).astype(np.float)", setup="from __main__ import np, data", number=N)
我同意@senderle的观点,如果你想做简单且精确的比较,并且可以使用整数,则通常会更容易。但是,如果您需要独特的浮点数,则也应该能够做到,尽管需要更加小心谨慎。 浮点数的主要问题在于可以进行计算时引入的小差异,在普通的print
中不会出现,但这并不是一个巨大的障碍,尤其是在对一定范围内的浮点数进行round, fix, rint
之后。