简体   繁体   English

numpy 4D数组高级索引与示例

[英]numpy 4D array advanced indexing with example

I am reading some deep learning code. 我正在阅读一些深度学习代码。 I have problem on advanced indexing in numpy array. 我在numpy数组中的高级索引有问题。 The code I was testing: 我正在测试的代码:

import numpy

x = numpy.arange(2 * 8 * 3 * 64).reshape((2, 8, 3, 64))
x.shape

p1 = numpy.arange(2)[:, None]
sd = numpy.ones(2 * 64, dtype=int).reshape((2, 64))
p4 = numpy.arange(128 // 2)[None, :]

y = x[p1, :, sd, p4]
y.shape

Why is the shape of y was (2, 64, 8) ? 为什么y的形状是(2, 64, 8)

Here is the output of the above code: 以下是上述代码的输出:

>>> x.shape
(2, 8, 3, 64)

>>> p1
array([[0], [1]])

>>> sd
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])

>>> p4
array([[ 0,  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, 31,
        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]])

>>> y.shape
(2, 64, 8)

I read this: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#advanced-indexing 我读到这个: https//docs.scipy.org/doc/numpy/reference/arrays.indexing.html#advanced-indexing

I think it is related to broadcasting: 我认为这与广播有关:

x shape is (2, 8, 3, 64) . x形状是(2, 8, 3, 64)

p1 is simple, it is array([[0], [1]]), just means selecting ind 0, 1 of 1st dimension. p1很简单,它是array([[0], [1]]),只是意味着选择第一维的ind 0, 1 and the double array is for broadcasting. 双数组用于广播。

p2 is : , which means select all 8 elements in 2nd dimension. p2: ,表示选择第二维中的所有8个元素。

p3 is tricky, it contains two “lists” to pick one out of 3 elements in dimension 3, so the resulting new 3rd dimension should be 1. p3很棘手,它包含两个“列表”来从维度3中的3个元素中选择一个,因此得到的新第三维应为1。

p4 means it selects all 64 elements in 4th dimension. p4表示它选择第四维中的所有64个元素。

So I think the y.shape should be (2, 8, 1, 64) . 所以我认为y.shape应该是(2, 8, 1, 64) y.shape (2, 8, 1, 64)

But the correct one is (2, 64, 8) . 但正确的是(2, 64, 8) Why? 为什么?

I had the same issue when I first encountered fancy indexing in numpy. 当我第一次遇到numpy中的花式索引时,我遇到了同样的问题。 The short answer is that there is no trick to it: fancy indexing just selects elements into an output of the same shape as the index. 简短的回答是没有技巧:花哨的索引只是选择元素到与索引相同形状的输出中。 With purely fancy indexing, your output array will be the same shape as your broadcasted index arrays ( described here ). 使用纯粹的花式索引,您的输出数组将与您的广播索引数组( 此处描述 )的形状相同。 The shape of the output has almost nothing to do with the shape of the input unless you throw in a regular slice index as well ( described here ). 输出的形状几乎与输入的形状无关 ,除非你引入常规切片索引( 这里描述 )。 Your case is the latter, which adds to the confusion. 你的案子是后者,这增加了混乱。

Let's take a look at your indices to see what is happening: 让我们来看看你的指数,看看发生了什么:

y = x[p1, :, sd, p4]
x.shape -> 2, 8, 3, 64
p1.shape -> 2, 1
sd.shape -> 2, 64
p4.shape -> 1, 64

The specific documentation on how to proceed is here: 有关如何继续的具体文档如下:

Two cases of index combination need to be distinguished: 需要区分两种索引组合:

  • The advanced indexes are separated by a slice, Ellipsis or newaxis . 高级索引由切片, Ellipsis或新newaxis For example x[arr1, :, arr2] . 例如x[arr1, :, arr2]
  • The advanced indexes are all next to each other. 高级索引彼此相邻。 For example x[..., arr1, arr2, :] but not x [arr1, :, 1] since 1 is an advanced index in this regard. 例如x[..., arr1, arr2, :]但不是x [arr1, :, 1]因为1在这方面是一个高级索引。

In the first case, the dimensions resulting from the advanced indexing operation come first in the result array, and the subspace dimensions after that. 在第一种情况下,高级索引操作产生的维度首先出现在结果数组中,然后是子空间维度。 In the second case, the dimensions from the advanced indexing operations are inserted into the result array at the same spot as they were in the initial array (the latter logic is what makes simple advanced indexing behave just like slicing). 在第二种情况下,高级索引操作的维度将插入到结果数组中与初始数组中相同的位置(后一种逻辑使简单的高级索引行为就像切片一样)。

Emphasis mine 强调我的

Keep in mind that in both cases described above, the dimensions of the fancy-indexed portion are the dimensions of the index arrays, not the array you are indexing. 请记住,在上述两种情况下,花式索引部分的尺寸是索引数组的尺寸,而不是您要编制索引的数组。

What you should expect to see, then, is something with the broadcasted dimensions of p1 , sd and p4 ( 2, 64 ), followed by the size of the second dimension of x ( 8 ). 你应该会看到什么,然后,是一些与广播尺寸p1sdp42, 64 ),其次是第二个维度的尺寸x8 )。 And that is indeed what you get: 这确实是你得到的:

>>> y.shape
(2, 64, 8)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM