Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何使包含numpy数组的元组可散列?_Python 3.x_Numpy_Tuples_Hashable - Fatal编程技术网

Python 3.x 如何使包含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

使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].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])