<p>在<code>-0.</code>和<code>+0.</code>之间存在的问题是浮动应该如何工作的规范(IEEE754)的一部分。在某些情况下,人们需要这种区别。例如,请参见在<a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html#numpy.around" rel="noreferrer">the docs for ^{<cd3>}</a>中链接到的文档。</p>
<p>值得注意的是,两个0应该比较为相等,所以</p>
<pre><code>np.array(-0.)==np.array(+0.)
# True
</code></pre>
<p>也就是说,我认为这个问题更可能与您的唯一性比较有关。例如:</p>
<pre><code>a = np.array([-1., -0., 0., 1.])
np.unique(a)
# array([-1., -0., 1.])
</code></pre>
<p>如果要将数字保留为浮点,但所有零都相同,可以使用:</p>
<pre><code>x = np.linspace(-2, 2, 6)
# array([-2. , -1.2, -0.4, 0.4, 1.2, 2. ])
y = x.round()
# array([-2., -1., -0., 0., 1., 2.])
y[y==0.] = 0.
# array([-2., -1., 0., 0., 1., 2.])
# or
y += 0.
# array([-2., -1., 0., 0., 1., 2.])
</code></pre>
<p>不过,请注意,您确实需要做这一点额外的工作,因为您正试图避免使用浮点规范。</p>
<p>还要注意,这不是由于舍入误差造成的。例如</p>
<pre><code>np.fix(np.array(-.4)).tostring().encode('hex')
# '0000000000000080'
np.fix(np.array(-0.)).tostring().encode('hex')
# '0000000000000080'
</code></pre>
<p>也就是说,得到的数字完全相同,但是</p>
<pre><code>np.fix(np.array(0.)).tostring().encode('hex')
# '0000000000000000'
</code></pre>
<p>是不同的。这就是为什么你的方法不起作用的原因,因为它比较的是数字的二进制表示,这对两个零是不同的。因此,我认为问题更多的是比较的方法,而不是比较浮点数的唯一性的一般思想。</p>
<p>各种方法的快速计时测试:</p>
<pre><code>data0 = np.fix(4*np.random.rand(1000000,)-2)
# [ 1. -0. 1. -0. -0. 1. 1. 0. -0. -0. .... ]
N = 100
data = np.array(data0)
print timeit.timeit("data += 0.", setup="from __main__ import np, data", number=N)
# 0.171831846237
data = np.array(data0)
print timeit.timeit("data[data==0.] = 0.", setup="from __main__ import np, data", number=N)
# 0.83500289917
data = np.array(data0)
print timeit.timeit("data.astype(np.int).astype(np.float)", setup="from __main__ import np, data", number=N)
# 0.843791007996
</code></pre>
<p>我同意@senderle的观点,如果您想要简单而精确的比较,并且可以使用int,那么int通常会更容易。但如果你想要独特的浮动,你也应该能够做到这一点,虽然你需要做得更仔细一点。浮动的主要问题是,可以有一些小的差异,这些差异可以从计算中引入,并且不会出现在正常的<code>print</code>中,但这并不是一个巨大的障碍,尤其是对于合理范围的浮动,在<code>round, fix, rint</code>之后。</p>