11

当我在 numpy 中创建一维数组并使用字符串(包含数字)对其进行索引时,我得到了预期的错误:

>>> import numpy as np
>>> a = np.arange(15)
>>> a['10']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: field named 10 not found.

但是,当我创建一个二维数组并使用两个字符串进行索引时,它没有给出错误并返回元素,就好像字符串首先转换为整数一样

>>> b = np.arange(15).reshape(3,5)
>>> b
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> b[1, 2]
7
>>> b['1', '2']
7

这是怎么回事?为什么我在二维情况下不会出错?

4

2 回答 2

2

免责声明——这个答案肯定是不完整的

我认为您所看到的是花哨的序列索引的结果。由于字符串实际上是序列,因此您一次获取一个字符的字符串值并将它们转换为 " intp" 对象(可能只是使用 python 的int函数)——然后为您提供数组索引。

这也解释了 1D 情况:

class Foo(object):
    def __getitem__(self,idx):
        print idx

a = Foo()
a[12]
a[12,12]

请注意,在第二种情况下tuple,传递了 a,而在第一种情况下,传递了一个整数。


这个测试证明了我仍然不明白的部分:

import numpy as np
a = np.arange(156).reshape(13,12)
print a[12,3] == a['12',3]   #True -- I would have thought False for this one...
print a['12',3] == a[('1','2'),3]  #False -- I would have guessed True for this..
assert( a[tuple('12'),3] == a[(1,2),3] )  #This passes, as expected

随意尝试在评论中向我解释这一点。:) 差异可能是 numpy 在转换为intp对象序列时故意留下字符串,以便更顺利地处理记录数组......

于 2012-10-31T13:15:49.513 回答
1

补充一点,请注意第一种情况(单个字符串)可能与对使用字符串作为字段名称的recarrays 的支持有关。

请不要依赖第二种情况。Numpy 在使用非数组进行索引方面非常自由,因为如果它是非数组(而不是切片,也不是 None),它会简单地尝试将其转换为整数数组,这对这些字符串进行了很好的定义。然而,这不是设计使然,因为太多的软件依赖于这种行为(至少部分地)来实际改变它,老实说,虽然这对于忘记被铸造的浮动有点意义,但它真的没有对于字符串。


@mgilson 的更多详细信息。考虑到所有这些都是标签外的使用,它真的归结为实现细节。例如,单个字符串当前对于recarrays 是特殊的,即使它不是recarray,但是字符串的元组仅对于recarrays 是特殊的。

现在,字符串列表有点特殊,因为它们不是元组,但在大多数情况下表现得像一个。这可能是一个小错误......因为它在其中找到了一个序列,所以它会触发花哨的索引,但“忘记”将其转换为数组。虽然我通常会使用元组来表示多个轴。

于 2012-10-31T14:05:13.303 回答