2010-12-06 14 views
77

Tengo una matriz 2D numpy. ¿Hay alguna forma de crear una vista que incluya las primeras filas k y todas las columnas?¿Ver en una matriz numpy?

El punto es evitar la copia de los datos subyacentes (la matriz es tan grande que la realización de copias parciales no es factible.)

Respuesta

188

Claro, sólo indexará como lo haría normalmente. P.ej. y = x[:k, :] Esto devolverá una vista en la matriz original. No se copiarán datos, y las actualizaciones realizadas en y se reflejarán en x y viceversa.


Editar:

que habitualmente trabajo con matrices> 10 GB de 3D de uint8, por lo que me preocupa mucho esto ... Numpy puede ser muy eficiente en la gestión de memoria si se mantiene un par de cosas en mente . Aquí hay algunos consejos sobre cómo evitar la realización de copias de matrices en la memoria:

Uso +=, -=, *=, etc para evitar hacer una copia de la matriz. P.ej. x += 10 modificará la matriz en su lugar, mientras que x = x + 10 hará una copia y la modificará. (También, echar un vistazo a numexpr)

Si desea hacer una copia con x = x + 10, ser conscientes de que x = x + 10.0 causará x ser automáticamente-fundido a una matriz de punto flotante, si no lo estaba ya. Sin embargo, x += 10.0, donde x es una matriz de enteros, causará que el 10.0 se redireccione a int con la misma precisión que la matriz.

Además, muchas de las funciones numpy tomar un parámetro out, por lo que puede hacer cosas como np.abs(x, x) tomar el valor absoluto de x en el lugar.


Como segunda edición, aquí está algunos consejos más sobre vistas vs. copias con matrices numpy:

A diferencia de las listas de Python, y = x[:] no devuelve una copia, devuelve una vista. Si no quiere una copia (que, por supuesto, duplicará la cantidad de memoria que está usando) use y = x.copy()

A menudo escuchará acerca de la "indización de lujo" de las matrices numpy. Usar una lista (o matriz de enteros) como índice es "indexación elegante". Puede ser muy útil, pero copia los datos.

Como un ejemplo de esto: y = x[[0, 1, 2], :] devuelve una copia, mientras que y = x[:3,:] devolvería una vista.

Incluso la indexación realmente loca como x[4:100:5, :-10:-1, None] es una indexación "normal" y devolverá una vista, así que no tema usar todo tipo de trucos de corte en arreglos grandes.

x.astype(<dtype>) devolverá una copia de los datos como el nuevo tipo, mientras que x.view(<dtype>) devolverá una vista.

Tenga cuidado con esto, sin embargo ... Es extremadamente potente 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 enteros, (o viceversa) numpy interpretará los bits subyacentes de la matriz como ints.

Por ejemplo, esto significa que 1.0 como un flotador de 64 bits en un sistema poco-endian habrá 4607182418800017408 cuando se ve como un int de 64 bits, y una serie de [ 0, 0, 0, 0, 0, 0, 240, 63] si visto como un uint8. Sin embargo, esto es realmente bueno cuando se necesita hacer pequeños giros de bits en arreglos grandes ... Usted tiene un control de bajo nivel sobre cómo se interpreta el búfer de memoria.

+0

Gracias por los muy buenos consejos! Estaba leyendo la guía del usuario de Numpy y confundí por qué 'x [np.array ([1, 1, 3, 1])] + = 1' modificado' x'. Ahora lo tengo! – tnq177

+0

Esta es una gran respuesta, gracias por compartir. – jlandercy

+0

buenos consejos! Tengo otra pregunta. ¿Cómo probar que Numpy no dispara una copia sino solo una vista? La identificación de Python() parece incapaz de esto. – wuhaochi

Cuestiones relacionadas