Tengo una variable, x, que tiene la forma (2,2,50,100).
También tengo una matriz, y, que es igual a np.array ([0,10,20]). Algo extraño sucede cuando indexo x [0,:,:, y].
x = np.full((2,2,50,100),np.nan)
y = np.array([0,10,20])
print(x.shape)
(2,2,50,100)
print(x[:,:,:,y].shape)
(2,2,50,3)
print(x[0,:,:,:].shape)
(2,50,100)
print(x[0,:,:,y].shape)
(3,2,50)
¿Por qué sale el último (3,2,50) y no (2,50,3)?
Respuestas:
Así es como numpy usa la indexación avanzada para transmitir formas de matriz. Cuando pasa un
0
para el primer índice, yy
para el último índice, numpy transmitirá el0
para que tenga la misma forma quey
. El siguiente equivalencia sostiene:x[0,:,:,y] == x[(0, 0, 0),:,:,y]
. Aquí hay un ejemploAhora, debido a que está pasando efectivamente dos conjuntos de índices, está utilizando la API de indexación avanzada para formar (en este caso) pares de índices.
Que tiene una primera dimensión igual a la longitud de
y
. Esto es lo que estás viendo.Como ejemplo, observe una matriz con 4 dimensiones que se describen en el siguiente fragmento:
x
tiene una forma secuencial realmente fácil de entender que ahora podemos usar para mostrar lo que está sucediendo ...La primera dimensión es como tener 2 libros de Excel, la segunda dimensión es como tener 3 hojas en cada libro, la tercera dimensión es como tener 4 filas por hoja, y la última dimensión es 5 valores para cada fila (o columnas por hoja).
Mirándolo de esta manera, preguntando
x[0,:,:,0]
, está el dicho: "en el primer libro de trabajo, para cada hoja, para cada fila, dame el primer valor / columna".Pero ahora con la indexación avanzada, podemos pensar
x[(0,0,0),:,:,y]
como "en el primer libro de trabajo, para cada hoja, para cada fila, dame ely
valor / columna th. Ok, ahora hazlo para cada valor dey
"Donde se vuelve loco es que numpy se transmitirá para que coincida con las dimensiones externas de la matriz de índice. Entonces, si desea hacer la misma operación que anteriormente, pero para AMBOS "libros de Excel", no tiene que hacer un bucle y concatenar. Puede pasar una matriz a la primera dimensión, pero DEBE tener una forma compatible.
Pasar un número entero se transmite a
y.shape == (3,)
. Si desea pasar una matriz como primer índice, solo la última dimensión de la matriz debe ser compatibley.shape
. Es decir, la última dimensión del primer índice debe ser 3 o 1.Encontré una breve explicación en los documentos: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
Editar:
De la pregunta original, para obtener una línea de su subslicing deseado, puede usar
x[0][:,:,y]
:Sin embargo, si está intentando asignar a esos subslices, debe tener mucho cuidado de ver una vista de memoria compartida de la matriz original. De lo contrario, la asignación no será a la matriz original, sino a una copia.
La memoria compartida solo ocurre cuando usa un número entero o un segmento para subconjuntar su matriz, es decir,
x[:,0:3,:,:]
ox[0,:,:,1:-1]
.Tanto en su pregunta original como en mi ejemplo
y
no se trata de un int o un sector, por lo que siempre se terminará asignando a una copia del original.¡PERO! Debido a que su matriz
y
puede expresarse como un segmento, usted PUEDE realmente obtener una vista asignable de su matriz a través de:Aquí usamos el segmento
0:21:10
para tomar cada índice que estaría enrange(0,21,10)
. Tenemos que usar21
y no20
porque el punto de parada está excluido del segmento, al igual que en larange
función.Básicamente, si puede construir un segmento que se ajuste a sus criterios de sublición, puede hacer la asignación.
fuente
Se llama
combining advanced and basic indexing
. Encombining advanced and basic indexing
numpy, primero haga la indexación en la indexación avanzada y subespacie / concatene el resultado a la dimensión de la indexación básica.Ejemplo de documentos:
así, adelante
x[0,:,:,y]
,0
yy
son indexación anticipada. Se transmiten juntos para producir dimensión(3,)
.Esta
(3,)
al comienzo de la 2da y 3ra dimensión para(3, 2, 50)
Para ver que la primera y la última dimensión realmente están transmitiendo en conjunto, puede intentar el cambio
0
a[0,1]
ver el error de la radiodifusiónfuente