Tengo una numpy
matriz 2D . ¿Hay alguna forma de crear una vista que incluya las primeras k
filas y todas las columnas?
El punto es evitar copiar los datos subyacentes (la matriz es tan grande que no es posible realizar copias parciales).
Claro, simplemente indexe como lo haría normalmente. Por ejemplo, y = x[:k, :]
esto devolverá una vista a la matriz original. No se copiará ningún dato y las actualizaciones realizadas y
se reflejarán en x
y viceversa.
Editar:
Normalmente trabajo con matrices 3D de> 10GB de uint8, así que me preocupo mucho por esto ... Numpy puede ser muy eficiente en la gestión de la memoria si tiene en cuenta algunas cosas. A continuación, se ofrecen algunos consejos para evitar realizar copias de matrices en la memoria:
Uso +=
, -=
, *=
, etc, para evitar hacer una copia de la matriz. Por ejemplo x += 10
, modificará la matriz en su lugar, mientras x = x + 10
que hará una copia y la modificará. (también, eche un vistazo a numexpr )
Si desea hacer una copia con x = x + 10
, tenga en cuenta que x = x + 10.0
hará que se actualice x
automáticamente a una matriz de punto flotante, si no lo estaba ya. Sin embargo, x += 10.0
donde x
es una matriz de enteros, hará 10.0
que se reduzca a un int de la misma precisión que la matriz.
Además, muchas funciones numpy toman un out
parámetro, por lo que puede hacer cosas como np.abs(x, x)
tomar el valor absoluto de x
in situ.
Como segunda edición, aquí hay algunos consejos más sobre vistas frente a copias con matrices numpy:
A diferencia de las listas de Python, y = x[:]
no devuelve una copia, devuelve una vista. Si desea una copia (que, por supuesto, duplicará la cantidad de memoria que está usando) usey = x.copy()
A menudo oirá hablar de "indexación elegante" de matrices numpy. Usar una lista (o matriz de números enteros) como índice es una "indexación elegante". Puede ser muy útil, pero copia los datos.
Como ejemplo de esto: y = x[[0, 1, 2], :]
devuelve una copia, mientras y = x[:3,:]
que devolvería una vista.
Sin embargo, incluso una indexación realmente loca como x[4:100:5, :-10:-1, None]
es una indexación "normal" y devolverá una vista, así que no tenga miedo de usar todo tipo de trucos de corte en matrices grandes.
x.astype(<dtype>)
devolverá una copia de los datos como el nuevo tipo, mientras x.view(<dtype>)
que devolverá una vista.
Sin embargo, tenga cuidado con esto ... Es extremadamente poderoso y útil, pero debe comprender cómo se almacenan los datos subyacentes en la memoria. Si tiene una matriz de flotantes y los ve como ints, (o viceversa) numpy interpretará los bits subyacentes de la matriz como ints.
Por ejemplo, esto significa que 1.0
como un flotante de 64 bits en un sistema little-endian se verá 4607182418800017408
como un int de 64 bits, y una matriz de [ 0, 0, 0, 0, 0, 0, 240, 63]
si se verá como un uint8. Sin embargo, esto es realmente bueno cuando necesita hacer cambios de bits de algún tipo en matrices grandes ... Tiene un control de bajo nivel sobre cómo se interpreta el búfer de memoria.
x[np.array([1, 1, 3, 1])] += 1
modificóx
. ¡Ahora lo tengo!b
es una vista dea
, entoncesb.base is a
seráTrue
. Una copia (de cualquier matriz) siempre tendráarr_copy.base is None