numpy数组中的索引方法是如何工作的?

slhcrj9b  于 2023-08-05  发布在  其他
关注(0)|答案(2)|浏览(68)

我在做一些无聊的问题,有一个关于这个数组的问题。

[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]
 [16 17 18 19 20]
 [21 22 23 24 25]
 [26 27 28 29 30]]

字符串
我必须得到11,12,16,17。解决方案是将数组索引为[2:4, 0:2]。这是怎么一回事?我期待的沿着[2, :3][11, 12][3, :2][16, 17]

uajslkp6

uajslkp61#

问'怎么样'有点模棱两可;你需要多少细节?

In [222]: arr = np.arange(1,31).reshape(6,5)
In [223]: arr
Out[223]: 
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25],
       [26, 27, 28, 29, 30]])

字符串
问题的这一部分表明您已经可以使用2部分数组索引:[12][13][14][15][16][17]18][19][1
但是如果我们更正第一个索引,选择两行和两列的模式变得更加明显:

In [224]: arr[2,:2]
Out[224]: array([11, 12])
In [225]: arr[3,:2]
Out[225]: array([16, 17])


然后可以组合成一个表达式:

In [226]: x = arr[2:4, :2]
In [227]: x
Out[227]: 
array([[11, 12],
       [16, 17]])


对于切片,这是basic indexing,结果是view

In [228]: x.base
Out[228]: 
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
       18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])


这与arange相同,它被重塑为arr(它本身是view)。
我们可以通过数组属性的dict显示来进一步探索该视图:

In [229]: arr.__array_interface__
Out[229]: 
{'data': (93936282518720, False),
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (6, 5),
 'version': 3}
In [230]: x.__array_interface__
Out[230]: 
{'data': (93936282518800, False),
 'strides': (40, 8),
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (2, 2),
 'version': 3}
In [231]: arr.strides
Out[231]: (40, 8)


x数组具有相同的步幅,但形状较小。data值是一个“指针”,指向数组在arange数字中的“开始”位置。x值有一个80字节的偏移量(.800-.720)。这是2*5*8字节(2行8字节整数)。这就是索引所要做的:返回一个新的数组对象,包含这些形状、步幅和数据指针值。
更详细地说:arr[2:4, :2]被解释器翻译为对getitem方法的调用,带有一个切片元组:

arr.__getitem__((slice(2,4,None), slice(0,2,None)))


到目前为止,这是标准的Python。由数组自己的代码来理解元组参数。列表会抱怨元组TypeError: list indices must be integers or slices, not tuple,但numpy数组可以使用它。(numpy.index_tricks有一些类使用这种元组技巧来产生一些伪索引语法。
有关如何使用基本索引的更多详细信息,请访问:
https://numpy.org/doc/stable/user/basics.indexing.html#basic-indexing
我们可以使用数组来选择相同的值,但这是advanced indexing

In [233]: arr[np.array([2,3])[:,None], np.array([0,1])]
Out[233]: 
array([[11, 12],
       [16, 17]])


结果不再是视图,它有自己的数据缓冲器。索引过程更加复杂。

s1ag04yj

s1ag04yj2#

[2:4]选择第2行和第3行(最上面的一行是0)。始终排除范围的末尾,因此未选择第4行。
[0:2]选择列0和1。

相关问题