La indexación de múltiples arrays multidimensionales depende de un método de segmentación

Tengo una matriz 3-D. Cuando tomo un segmento 2-D, el resultado depende de si está indexado con una lista o con un sector. En el primer caso se transpone el resultado. No encontré este comportamiento en el manual .

>>> import numpy as np >>> x = np.array([[[1,1,1],[2,2,2]], [[3,3,3],[4,4,4]]]) >>> x array([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]) >>> x[0,:,[0,1]] array([[1, 2], [1, 2]]) >>> x[0,:,slice(2)] array([[1, 1], [2, 2]]) >>> 

¿Podría alguien señalar una razón para esto?

Como lo entiendo, NumPy está siguiendo la filosofía de numeración de ejes cuando arroja el resultado cuando se le da un índice similar a una list/tuple .

 array([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]) 

Cuando ya especifica los dos primeros índices ( x[0, :, ] ), ahora la siguiente pregunta es cómo extraer la tercera dimensión. Ahora, cuando especifica una tupla (0,1) , primero extrae el 0º eje del corte, por lo que obtiene [1, 2] ya que se encuentra en el 0º eje, luego extrae la 1ª rebanada del mismo modo y se astack debajo del fila ya existente [1, 2] .

 [[1, 1, 1], array([[1, 2], [2, 2, 2]] =====> [1, 2]]) 

(visualice este astackmiento como se muestra abajo ( no encima de ) la fila ya existente ya que el eje 0 crece hacia abajo) introduzca la descripción de la imagen aquí

Alternativamente, está siguiendo la filosofía de corte ( start : stop : step ) cuando se proporciona el slice(n) para el índice. Tenga en cuenta que usar slice(2) es esencialmente igual a 0:2 en su ejemplo. Entonces, extrae [1, 1] primero, luego [2, 2] . Tenga en cuenta, aquí cómo [1, 1] viene sobre [2, 2] , de nuevo siguiendo la misma filosofía de eje aquí ya que todavía no hemos abandonado la tercera dimensión. Por eso este resultado es la transposición del otro.

 array([[1, 1], [2, 2]]) 

Además, tenga en cuenta que a partir de matrices 3-D se mantiene esta consistencia. A continuación se muestra un ejemplo de la matriz 4-D y los resultados del corte.

 In [327]: xa Out[327]: 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]]]]) In [328]: xa[0, 0, :, [0, 1]] Out[328]: array([[0, 3, 6], [1, 4, 7]]) In [329]: xa[0, 0, :, 0:2] Out[329]: array([[0, 1], [3, 4], [6, 7]]) 

Porque en realidad estás usando indexación avanzada cuando usas [0,1] . De los documentos :

Combinando indexación avanzada y básica.

Cuando hay al menos una np.newaxis ( np.newaxis , puntos suspensivos ( ... ) o np.newaxis en el índice (o la matriz tiene más dimensiones que índices avanzados), entonces el comportamiento puede ser más complicado. Es como concatenar el resultado de indexación para cada elemento de índice avanzado

En el caso más simple, solo hay un único índice avanzado. Un solo índice avanzado puede, por ejemplo, reemplazar una porción y la matriz de resultados será la misma, sin embargo, es una copia y puede tener un diseño de memoria diferente . Una rebanada es preferible cuando es posible.

Preste atención a las dos partes que he en negrita arriba.

En particular, en esta construcción:

 >>> x[0,:,[0,1]] array([[1, 2], [1, 2]]) 

Es el caso donde hay al menos una vez “slice, ellipsisi o np.newaxis” en el índice, y el comportamiento es como concatenar el resultado de la indexación para cada elemento de índice avanzado . Asi que:

 >>> x[0,:,[0]] array([[1, 2]]) >>> x[0,:,[1]] array([[1, 2]]) >>> np.concatenate((x[0,:,[0]], x[0,:,[1]])) array([[1, 2], [1, 2]]) 

Sin embargo, esta construcción es como el caso simple: solo hay un único índice avanzado, por lo que actúa como una porción:

 >>> x[0,:,slice(2)] array([[1, 1], [2, 2]]) >>> x[slice(0,1),:,slice(2)] array([[[1, 1], [2, 2]]]) 

Aunque tenga en cuenta que lo último es en realidad tridimensional porque la primera parte del índice actuó como una porción, son 3 porciones y tres dimensiones.