“元组”numpy 数组的 Python 哈希

问题描述 投票:0回答:1

我有一个类

MyClass
,其中每个实例存储像素的 x 和 y 坐标,表示为两个 1D numpy 数组(长度相同)。如果两个实例的坐标数组相同(包括
nan
),则认为它们相等。
我尝试了两种散列方法:一种是将两个数组转换为元组并对它们进行散列,另一种是为每个数组调用
tobytes()
方法:

class MyClass:
  # ... init, doA(), doB(), etc. ...
  def __eq__(self, other):
    if not type(self) == type(other):
      return False
    if not np.array_equal(self._x, other._x, equal_nan=True):
      return False
    if not np.array_equal(self._y, other._y, equal_nan=True):
      return False
    return True

  def hash1(self):
    return hash((tuple(self._x), tuple(self._y)))

  def hash2(self):
    return hash((self._x.tobytes(), self._y.tobytes()))

在同一个实例上调用

hash1
会产生不同的哈希值,并且调用
hash2
每次都会输出相同的结果。为什么它们的行为如此不同?

python numpy hash
1个回答
0
投票

NumPy 数组不会将其元素存储为 Python 对象(除非您使用 dtype=object)。它存储原始硬件数值。这意味着当您调用

tuple
时,数组必须为所有元素创建 Python 对象。例如,如果您的数组的数据类型为 float64,则该数组必须生成
numpy.float64
的实例。

数组不保存这些包装对象。每次调用

tuple
时,数组都会生成新的包装对象。具有 NaN 值的
numpy.float64
的两个实例不能保证散列相同,因此如果您的数组包含 NaN,则散列元组不能保证产生一致的结果。

© www.soinside.com 2019 - 2024. All rights reserved.