当我在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
发生了什么事?为什么我在二维情况下没有出错?
答案 0 :(得分:2)
免责声明 - 这个答案肯定是不完整的
我认为你所看到的是fancy sequence indexing的结果。因为字符串实际上是序列,所以你一次得到字符串的值一个字符并将它们转换为“intp
”对象(可能只是使用python的int
函数) - 然后是给你你的数组索引。
这也解释了一维案例:
class Foo(object):
def __getitem__(self,idx):
print idx
a = Foo()
a[12]
a[12,12]
请注意,在第二种情况下,传递tuple
,而在第一种情况下传递整数。
这个测试证明了我仍然不理解的部分:
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
对象序列时故意留下字符串,以便更顺畅地处理记录数组......
答案 1 :(得分:1)
只是要添加,请注意第一种情况(单个字符串),可能与支持重新排列有关,它使用字符串作为字段名称。
请不依赖第二种情况。 Numpy非常自由地使用非数组进行索引,因为如果它是非数组(而不是切片而不是None),它将只是尝试将其转换为整数数组,这是为这些字符串定义的。然而,这是不设计,因为太多的软件依赖于这种行为(至少部分地)来实际改变它,而且老实说,虽然这对于那些被遗忘的花车有些意义演员,它真的不适用于弦乐。
@mgilson的更多细节。考虑到所有这些都是标签使用,它真的很适合实现细节。例如,单个字符串当前特别用于重新排列,即使它不是重新排列,但字符串元组只是特殊的重新排列。
现在一个字符串列表,有些特殊,因为它们不是元组,但就像当时的大多数一样。这可能是一个小错误...因为它在其中找到一个序列,它会触发花哨的索引,但“忘记”将其转换为数组。虽然我通常会使用元组来表示多个轴。