【发布时间】:2021-05-06 14:18:45
【问题描述】:
已经注意到 numpy 中关于区分 -0.0 和 0.0 的一些相当特殊的行为。以下是一些示例:
#normal python doesn't distinguish between 0 and -0:
>>> -0
0
>>> -0==0
True
#numpy also sometimes changes -0 to 0:
>>> import numpy as np
>>> np.array([-0])
array([0])
#HERE IS THE SURPRISE - numpy does seem to have separate 0 and -0:
>>> np.round(0.1)
0.0
>>> np.round(-0.1)
-0.0
#yet numpy is of course aware that -0 and 0 are equal:
>>> np.round(-0.1) == np.round(0.1)
True
#python round() function doesn't behave like this:
>>> round(0.1)
0
>>> round(-0.1)
0
背景 - 我为什么要关心这个?因为我有一个 numpy 数组列表,并且我想将与列表中另一个数组相等的数组删除为 2d.p.。为此,我将数组列表更改为数组字典,其中每个数组的键item 是舍入为 2d.p 的数组。现在一个数组不能作为dict key,所以我在四舍五入后使用了.tobytes(),并且四舍五入后的数组的字节表示就是item的key。该项目的值是未舍入的数组,因为我想保持精度。
想象一下,当我注意到这并没有消除相同的数组时,我感到很惊讶,这仅仅是因为一个有一个 -0 而另一个有一个 0...
>>> np.round(0.1).tobytes() #ends with x00
b'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> np.round(-0.1).tobytes() #ends with x80
b'\x00\x00\x00\x00\x00\x00\x00\x80'
>>> np.round(0.1).tobytes() == np.round(-0.1).tobytes() #well obviously this will be False
False
为什么 numpy 以不同的方式存储 -0 和 0,为什么有时而不总是?还有其他这种行为的例子吗 - 以上是我迄今为止提出的。为什么 numpy 在这方面与 python 不同?当python也有单独的0和-0时,有什么例子吗?如何让我的代码识别数组中一个位置的 -0 和 0 是相同的?如果您有 -0.0,则 adding 0 会将其更改为 0,但 subtracting 0 会将其保留为 -0.0。这是为什么呢?
【问题讨论】:
-
对于第一个问题,这是由于 IEEE-754 标准。数字需要标准化以避免这种情况。对于第二点,我想 oskros 的链接提供了答案。
-
酷 - 来自 oskros 的链接建议通过向数组添加 0.0 来进行标准化。
-
@oskros 谢谢 - 我没能找到那个帖子,但已经发现自己添加零有帮助。我的问题的主要目的是关于 为什么 这一切都像这样工作的理论方面,而不是如何解决这个问题。事实上,即使我写的答案(加零)也清楚地表明,虽然这有效,但我错过了这一切背后的基本理解和逻辑
-
@JérômeRichard 感谢有关 IEEE-754 的信息。这种行为的解释是什么?为什么标准设置为具有单独的 0 和 -0,当测试相等时返回 True,而在数学上(我假设)没有单独的 0 和 -0?