Numpy 使用标量数组作为键

Numpy 使用标量数组作为键,numpy,Numpy,这很有效 range(50)[np.asarray(10)] {}.get(50) 这很有效 range(50)[np.asarray(10)] {}.get(50) 这不是因为不可损坏的类型:“numpy.ndarray” {}.get(np.asarray(50)) 在这种情况下,没有实现\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu有什么原因吗?Python字典需要它们的键来实现\uuuuuuuuuueq\uuuu

这很有效

range(50)[np.asarray(10)]
{}.get(50)
这很有效

range(50)[np.asarray(10)]
{}.get(50)
这不是因为
不可损坏的类型:“numpy.ndarray”

{}.get(np.asarray(50))

在这种情况下,没有实现
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
有什么原因吗?

Python字典需要它们的键来实现
\uuuuuuuuuueq\uuuuuuuuuuuuuuuu
方法,Python的数据模型要求:

  • 对象的哈希在其生存期内不会更改
  • 如果
    x==y
    那么
    hash(x)==hash(y)
  • Numpy的
    ndarray
    类重写
    \uuuu eq\uuuu
    以支持元素级比较和广播。这意味着对于numpy数组
    x
    y
    x==y
    不是布尔数组,而是另一个数组。这本身可能排除了
    ndarray
    s作为字典键的正确功能

    即使忽略了
    ndarray.\uuuueq\uuuuu
    的这一怪癖,也很难想出
    ndarray.\uuuuu散列
    的(有用的)实现。由于numpy数组中的数据是可变的,因此我们无法使用该数据来计算
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>而不违反对象的哈希在其生命周期


    为可变对象定义
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    没有什么错,前提是哈希本身在对象的生命周期内不会改变。类似地,字典键可以是可变的,只要它们实现了
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。例如,简单的用户定义类是可变的,但仍然可以用作字典键。

    标量数组是具有0d形状的规则数组。否则就没有什么特别的了

    In [46]: x=np.array(10)
    In [47]: x
    Out[47]: array(10)
    In [48]: x[...]=100
    In [49]: x
    Out[49]: array(100)
    
    您必须从数组中提取数字:

    In [53]: {}.get(x)
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-53-19202767b220> in <module>()
    ----> 1 {}.get(x)
    
    TypeError: unhashable type: 'numpy.ndarray'
    In [54]: {}.get(x.item())
    In [58]: {}.get(x[()])
    

    如果您想切实做到这一点,请参见以下问题:但这不是您问题的答案,为什么?
    列表(或
    dict
    )也没有实现
    哈希
    )。它是为不可变的
    元组实现的。即使对
    [50]
    来说也是如此。字典的
    键必须是不可变的。数组或列表的索引可以是可变的数字。通常情况下,
    scalar-ndarray
    除了作为多维数组的副产品外,没有什么用处。