python – numpy ndarray哈希性

我有一些问题,了解如何管理numpy对象的哈希性.

>>> import numpy as np
>>> class Vector(np.ndarray):
...     pass
>>> nparray = np.array([0.])
>>> vector = Vector(shape=(1,), buffer=nparray)
>>> ndarray = np.ndarray(shape=(1,), buffer=nparray)
>>> nparray
array([ 0.])
>>> ndarray
array([ 0.])
>>> vector
Vector([ 0.])
>>> '__hash__' in dir(nparray)
True
>>> '__hash__' in dir(ndarray)
True
>>> '__hash__' in dir(vector)
True
>>> hash(nparray)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'numpy.ndarray'
>>> hash(ndarray)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'numpy.ndarray'
>>> hash(vector)
-9223372036586049780
>>> nparray.__hash__()
269709177
>>> ndarray.__hash__()
269702147
>>> vector.__hash__()
-9223372036586049780
>>> id(nparray)
4315346832
>>> id(ndarray)
4315234352
>>> id(vector)
4299616456
>>> nparray.__hash__() == id(nparray)
False
>>> ndarray.__hash__() == id(ndarray)
False
>>> vector.__hash__() == id(vector)
False
>>> hash(vector) == vector.__hash__()
True

怎么来的

> numpy对象定义一个__hash__方法,但是不是可以哈希的
>派生numpy.ndarray的类定义__hash__并且是可散列的?

我错过了什么吗?

我使用的是Python 2.7.1和numpy 1.6.1

感谢任何帮助!

编辑:添加对象ids

EDIT2:
并且在deinonychusaur评论之后,试图弄清楚哈希是否基于内容,我用numpy.nparray.dtype玩,有一些我觉得很奇怪的:

>>> [Vector(shape=(1,), buffer=np.array([1], dtype=mytype), dtype=mytype) for mytype in ('float', 'int', 'float128')]
[Vector([ 1.]), Vector([1]), Vector([ 1.0], dtype=float128)]
>>> [id(Vector(shape=(1,), buffer=np.array([1], dtype=mytype), dtype=mytype)) for mytype in ('float', 'int', 'float128')]
[4317742576, 4317742576, 4317742576]
>>> [hash(Vector(shape=(1,), buffer=np.array([1], dtype=mytype), dtype=mytype)) for mytype in ('float', 'int', 'float128')]
[269858911, 269858911, 269858911]

我很困惑…有些(类型独立)缓存机制在numpy?

最佳答案
我在Python 2.6.6和numpy 1.3.0中得到相同的结果.根据the Python glossary,如果定义了__hash__(并且不是None),则定义一个对象可以是hashable,而__eq__或__cmp__被定义. ndarray .__ eq__和ndarray .__ hash__都被定义并返回一些有意义的东西,所以我不明白为什么哈希应该失败.经过一个快速的谷歌,我发现this post on the python.scientific.devel mailing list,它表示数组从来没有打算是可以哈希 – 所以为什么ndarray .__哈希定义,我不知道.注意isinstance(nparray,collections.Hashable)返回True.

编辑:请注意,nparray .__ hash __()返回与id(nparray)相同,所以这只是默认的实现.也许在早期版本的python中删除__hash__的执行是很困难或不可能的(__hash__ =无技术显然在2.6中引入),所以他们使用某种C API魔法来实现这一点,不会传播到子类,并且不会阻止你明确地调用ndarray .__ hash__?

Python 3.2.2中的内容和repo中的当前numpy 2.0.0不同. __cmp__方法不再存在,所以hashability现在需要__hash__和__eq__(见Python 3 glossary).在这个版本的numpy中,ndarray .__ hash__被定义,但它只是None,所以不能被调用. hash(nparray)failed andisinstance(nparray,collections.Hashable)如预期的那样返回False.哈希(矢量)也失败.

转载注明原文:python – numpy ndarray哈希性 - 代码日志