Python - 在字典中使用numpy数组作为键的替代方法

33

我对Python的numpy相当新。在我的一个函数中,我尝试将numpy数组用作字典的键,并被Python解释器告知numpy数组不可哈希。我刚刚发现解决这个问题的一种方法是使用repr()函数将numpy数组转换为字符串,但这似乎非常昂贵。有没有更好的方法来实现相同的效果?

更新:我可以创建一个新的类来容纳numpy数组,这似乎是我想要实现的正确方法。只是想知道是否有更好的方法。

更新2:使用一个类来容纳数组中的数据,然后覆盖__hash__函数是可接受的,然而,我更喜欢@hpaulj提供的解决方案。将array/list转换为tuple更适合我的需求,因为它不需要额外的类。


你为什么想要使用一个numpy数组(无论以何种形式)作为字典键? - Jon Clements
你可以使用numpy数组中的数据来创建一个“哈希”,这个哈希可以作为字典的键使用。 - ZdaR
@JonClements 我需要一个字典,将一个一维向量映射到一组点。 - JZ_42
@ZdaR 我会尝试的。谢谢。 - JZ_42
6
尝试使用 tuple(A.tolist())。对于一维数组,这种转换很简单。 - hpaulj
@hpaulj 我已经使用了一个类来包含我的数组,但是您的建议完美地解决了问题!非常感谢您。您介意将此评论作为答案发布,以便我可以将其标记为已接受吗? - JZ_42
3个回答

32
如果您想快速将 numpy.ndarray 存储为字典中的一个键,快速方法是使用 ndarray.tobytes(),它会返回一个原始的 Python bytes 字符串,它是不可变的。
my_array = numpy.arange(4).reshape((2,2))
my_dict = {}
my_dict[my_array.tobytes()] = None

3
+2 指的是在密钥创建过程和密钥长度方面的效率提高。 - mork
这太棒了。既简单又高效。 - JZ_42
喜欢这个。正是我所寻找的。 - Tom Bennett
2
当数组的形状不同时,使用hash(array.data.tobytes())时必须小心。例如,np.zeros((2, 1))np.zeros((1, 2))具有相同的字节。 - Daniel S.

12

在做了一些研究并阅读了所有评论后,我想我已经知道了自己问题的答案,所以我会写下来。

  1. 编写一个类以包含 array 中的数据,然后重写 __hash__ 函数以更改如ZdaR所提到的哈希方式。
  2. 将此 array 转换为 tuple,即可立即使列表变得可哈希化。感谢hpaulj

我更喜欢方法2,因为它更适合我的需求,而且更简单。但是,使用一个类可能会带来一些额外的好处,因此也可能有用。


6
我认为如果您添加一个代码片段,那对于未来的读者会更好。 - Nagabhushan S N

-3

我刚遇到了这个问题,使用列表推导式有一个非常简单的解决方案:

import numpy as np

dict = {'key1':1, 'key2':2}
my_array = np.array(['key1', 'key2'])

result = np.array( [dict[element] for element in my_array] )
print(result)

结果应该是:

[1 2]

我不知道这有多高效,但似乎是一个非常实用和直接的解决方案,无需转换或新类 :)


这与问题无关。你字典中的键只是字符串('key1''key2')。 - tiao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接