Hoy, cuando usé el operador de división para modificar una matriz, descubrí que las siguientes operaciones obtuvieron resultados diferentes, aunque las operaciones parecían ser las mismas.
import numpy as np a = np.array([[1,2,3],[0,5,4],[4,5,3],[5,8,7]]) print(a) a[[0,1],:][0:2,:] = [[11,12,13],[8,9,7]] print(a) a[0:2,:][[0,1],:] = [[11,12,13],[8,9,7]] print(a)los resultados son los siguientes:
[[1 2 3] [0 5 4] [4 5 3] [5 8 7]] [[1 2 3] [0 5 4] [4 5 3] [5 8 7]] [[11 12 13] [8 9 7] [4 5 3] [5 8 7]]Supongo que "a[[0,1],:]" crea una nueva matriz y "a[0:2,:]" no. ¿Pero por qué? Estoy confundido. Quiero saber bajo qué condiciones se creará una nueva matriz cuando use el operador de división.
a[[0,1],:] con una lista es "indexación avanzada". Hace una copia. El [0,1] no es un segmento.
a[0:2,:] con un segmento es "indexación básica". Devuelve una view .
a[[0,1],:][0:2,:] = ... intenta modificar esa copia y no afecta a a archivo . a[0:2,:][[0,1],:] = ... intenta modificar la view y, por lo tanto, también modifica a .
a[[0,1],:] = ... modificará con éxito a archivo .
Es una buena idea evitar la secuencia de indexación al establecer valores. a[...][...] = ... . Como muestra este ejemplo, a veces funciona, otras veces no. Si lo evita por completo, no tendrá que preocuparse por cuál funciona.
Incluso cuando se obtienen valores, la doble indexación es menos que ideal. Siempre funciona, pero puede ser más difícil de entender.
a[0:2,:][[0,1],:] = [[11,12,13],[8,9,7]]se evalúa como
a.__getitem__((slice(0,2), slice(None))). __setitem__(([0,1], slice(None)), [[11,12,13],[8,9,7] ) El getitem se realiza primero y el setitem se aplica a ese resultado. Entonces, al encadenar la indexación, es crucial que comprenda lo que hace esa primera indexación.