Python 3.x 如何使包含numpy数组的元组可散列?
使numpy数组可散列的一种方法是将其设置为只读。这在过去对我很有效。但是当我在一个元组中使用这样一个numpy数组时,整个元组就不再是可散列的,我不明白这一点。以下是我为说明问题而编写的示例代码:Python 3.x 如何使包含numpy数组的元组可散列?,python-3.x,numpy,tuples,hashable,Python 3.x,Numpy,Tuples,Hashable,使numpy数组可散列的一种方法是将其设置为只读。这在过去对我很有效。但是当我在一个元组中使用这样一个numpy数组时,整个元组就不再是可散列的,我不明白这一点。以下是我为说明问题而编写的示例代码: import numpy as np npArray = np.ones((1,1)) npArray.flags.writeable = False print(npArray.flags.writeable) keySet = (0, npArray) print(keySet[1].fla
import numpy as np
npArray = np.ones((1,1))
npArray.flags.writeable = False
print(npArray.flags.writeable)
keySet = (0, npArray)
print(keySet[1].flags.writeable)
myDict = {keySet : 1}
首先,我创建一个简单的numpy数组并将其设置为只读。然后我将它添加到一个元组中,并检查它是否仍然是只读的(实际上是只读的)
当我想使用元组作为字典中的键时,我得到了错误TypeError:unhabletype:'numpy.ndarray'
下面是我的示例代码的输出:
False
False
Traceback (most recent call last):
File "test.py", line 10, in <module>
myDict = {keySet : 1}
TypeError: unhashable type: 'numpy.ndarray'
False
假的
回溯(最近一次呼叫最后一次):
文件“test.py”,第10行,在
myDict={keySet:1}
TypeError:不可损坏的类型:“numpy.ndarray”
如何使元组可散列?为什么Python首先显示这种行为?最快的实现方法
您可以做的不是使用元组定义类:
class KeySet(object):
def __init__(self, i, arr):
self.i = i
self.arr = arr
def __hash__(self):
return hash((self.i, hash(self.arr.tostring())))
现在,您可以在dict中使用它:
In [21]: ks = KeySet(0, npArray)
In [22]: myDict = {ks: 1}
In [23]: myDict[ks]
Out[23]: 1
你声称
使numpy数组可散列的一种方法是将其设置为只读
但事实并非如此。将数组设置为只读只会使其只读。由于多种原因,它不能使数组可散列
第一个原因是writeable
标志设置为False
的数组仍然是可变的。首先,您始终可以再次设置writeable=True
,然后继续向其写入,或者执行更奇特的操作,例如重新指定其形状
,即使writeable
为False
。其次,即使不触及数组本身,也可以通过另一个具有writeable=True
的视图来改变其数据
>>> x = numpy.arange(5)
>>> y = x[:]
>>> x.flags.writeable = False
>>> x
array([0, 1, 2, 3, 4])
>>> y[0] = 5
>>> x
array([5, 1, 2, 3, 4])
其次,要使哈希性有意义,对象首先必须是可等式的-==
必须返回布尔值,并且必须是等价关系。NumPy阵列不能做到这一点。散列值的目的是快速定位相等的对象,但是当您的对象甚至没有内置的相等概念时,提供散列就没有多大意义了
你不会得到包含数组的可散列元组。你甚至不会得到散列数组。最接近的方法是在元组中放入数组数据的其他表示形式。您是从哪里想到将
writeable
标志设置为False
将使数组可散列的?即使在将元组放入图片之前,这也不起作用。numpy数组没有所需的哈希方法(类似于\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu
)。该方法如下所述:这感觉像是pythonic,thx的快速答案!我还可以用一个包装numpy.fromstring()的函数将其转换回来,这是我稍后需要的。还有tobytes()
+1,感谢您对内部的说明。如果对数组进行散列的想法不存在,我必须首先将其转换为字符串。是否可以在numpy数组周围创建某种包装器,使它们可以散列和相等?这样就不必在数组的字节/字符串等表示形式之间来回移动了?
>>> x = numpy.arange(5)
>>> y = x[:]
>>> x.flags.writeable = False
>>> x
array([0, 1, 2, 3, 4])
>>> y[0] = 5
>>> x
array([5, 1, 2, 3, 4])