Numpy: vistas vs copia por rebanar

Cuando estoy haciendo el corte, ocurrió algo inesperado que parece ser el primero en verse pero el segundo es copiar.

primero

Primero rebanada de fila, luego rebanada de columna. Parece que es una vista.

>>> a = np.arange(12).reshape(3, 4) >>> a[0:3:2, :][:, [0, 2]] = 100 >>> a array([[100, 1, 100, 3], [ 4, 5, 6, 7], [100, 9, 100, 11]]) 

Segundo

Pero si primero hago un corte de columna, luego un corte de fila, parece una copia:

 >>> a[:, [0, 2]][0:3:2, :] = 0 >>> a array([[100, 1, 100, 3], [ 4, 5, 6, 7], [100, 9, 100, 11]]) 

Estoy confundido porque los dos métodos finalmente harán que parezca que la posición cambia, pero ¿por qué el segundo en realidad no cambia el número?

Todo lo que importa es si usted divide por filas o por columnas. La división por filas puede devolver una vista porque es un segmento contiguo de la matriz original. La segmentación por columna debe devolver una copia porque no es un segmento contiguo. Por ejemplo:

 A1 A2 A3 B1 B2 B3 C1 C2 C3 

De forma predeterminada, se almacena en la memoria de esta manera:

 A1 A2 A3 B1 B2 B3 C1 C2 C3 

Así que si quieres elegir cada segunda fila, es:

 [A1 A2 A3] B1 B2 B3 [C1 C2 C3] 

Esto se puede describir como {start: 0, size: 3, stride: 6} .

Pero si quieres elegir cada segunda columna:

 [A1] A2 [A3 B1] B2 [B3 C1] C2 [C3] 

Y no hay manera de describir eso usando un inicio, tamaño y paso. Así que no hay manera de construir tal visión.

Si desea poder ver cada segunda columna en lugar de cada segunda fila, puede construir su matriz en orden de Fortran, también conocido como column-major:

 np.array(a, order='F') 

Entonces será almacenado como tal:

 A1 B1 C1 A2 B2 C2 A3 B3 C3 

La respuesta aceptada por John Zwinck es en realidad falsa (¡simplemente lo descubrí de la manera más difícil!). El problema en la pregunta es una combinación de hacer “indexación de valores” con la indexación elegante de numpy. El siguiente documento explica exactamente este caso.

https://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html

en la sección “Pero la indexación elegante parece devolver vistas a veces, ¿no es así?”