Dem*_*nto 1 tuples numpy python-3.x 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].flags.writeable)
myDict = {keySet : 1}
Run Code Online (Sandbox Code Playgroud)
首先,我创建一个简单的numpy数组并将其设置为只读。然后,将其添加到元组,并检查它是否仍是只读的(它是)。
当我想使用元组作为字典中的键时,出现错误TypeError: unhashable type: 'numpy.ndarray'。
这是我的示例代码的输出:
False
False
Traceback (most recent call last):
File "test.py", line 10, in <module>
myDict = {keySet : 1}
TypeError: unhashable type: 'numpy.ndarray'
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能使我的元组可哈希化?为什么Python首先显示这种行为?
你声称
使numpy数组可哈希化的一种方法是将其设置为只读
但这不是真的。将数组设置为只读只会使其变为只读。由于多种原因,它不会使数组成为可散列的。
第一个原因是writeable标记设置为的数组False仍然可变。首先,您始终可以writeable=True重新设置并继续对其进行写入,或者进行更多奇特的操作,例如,shape即使writeableis 仍然重新分配它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])
Run Code Online (Sandbox Code Playgroud)
其次,为了使散列性有意义,对象必须首先是相等的 - ==必须返回布尔值,并且必须是等价关系。NumPy数组不这样做。哈希值的目的是快速定位相等的对象,但是当您的对象甚至没有内置的相等性概念时,提供哈希就没有多大意义。
您不会获得带有数组的可哈希元组。您甚至都不会获得可散列的数组。您可以获得的最接近的结果是将数组数据的其他表示形式放入元组中。
散列 numpy 数组的最快方法可能是 tostring。
In [11]: %timeit hash(y.tostring())
Run Code Online (Sandbox Code Playgroud)
你可以做的是而不是使用元组定义一个类:
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())))
Run Code Online (Sandbox Code Playgroud)
现在你可以在字典中使用它:
In [21]: ks = KeySet(0, npArray)
In [22]: myDict = {ks: 1}
In [23]: myDict[ks]
Out[23]: 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2229 次 |
| 最近记录: |