2009-10-07 9 views
11

Tengo una serie de archivos de texto de gran tamaño (hasta 1 gig) que se generan a partir de un experimento que debe analizarse en Python. Estarían mejor cargan en una matriz numpy 2D, que presenta la primera pregunta: ¿Creando incrementalmente una matriz numpy y midiendo el uso de la memoria

  • Como se sabe al comienzo de la carga del número de filas, ¿cómo puede un arsenal muy grande numpy se construirán de manera más eficiente, ¿fila por fila?

Simplemente agregando la fila a la matriz sería ineficaz en términos de memoria, ya que dos grandes matrices coexistirían momentáneamente. El mismo problema parece ocurrir si usa numpy.append. Las funciones stack son prometedoras, pero idealmente querría hacer crecer la matriz en su lugar.

Esto lleva a la segunda pregunta: ¿

  • ¿Cuál es la mejor manera de observar el uso de memoria de un programa Python que en gran medida utiliza matrices numpy?

Para estudiar el problema anterior, he utilizado las herramientas habituales de generación de perfiles de memoria (Heapy y Pimpighter) pero obtengo el tamaño de los objetos de la matriz externa (80 bytes) y no los datos que contienen. Aparte de una medición cruda de cuánta memoria está usando el proceso de Python, ¿cómo puedo obtener el tamaño "completo" de las matrices a medida que crecen?

Detalles locales: OSX 10.6, Python 2.6, pero las soluciones generales son bienvenidas.

Respuesta

7

No hay manera de asegurarse de que pueda hacer crecer la matriz en lugar de crear una matriz vacía (numpy.empty) del tamaño máximo posible y luego usar una vista de eso al final. No puede comenzar pequeño porque no hay garantía de que pueda expandir cualquier memoria que tenga el mapa sin destruir otros datos. (Y todo esto es mucho más bajo que el que Python le permite obtener desde el intérprete).

Su mejor opción es probablemente numpy.fromiter. Al observar la fuente, a medida que aumenta el número de elementos, la matriz se expande un poco más del 50% cada vez. Si puede obtener fácilmente el número de filas (digamos al contar las líneas), incluso puede pasarle una cuenta.

1

En la posible opción es hacer una sola pasada a través del archivo primero para contar el número de filas, sin cargarlas.

La otra opción es duplicar el tamaño de su mesa cada vez, que tiene dos beneficios:

  1. Sólo tendrá registro de memoria re-alloc (n) veces, donde n es el número de filas.
  2. Sólo necesita 50% más memoria RAM que el tamaño de la tabla más grande

Si se toma la ruta dinámica, se puede medir la longitud de la primera fila en bytes, entonces adivinar el número de filas mediante el cálculo (num bytes en bytes de archivos/números en la primera fila). Comience con una tabla de este tamaño.

+0

Gracias a todos. Dado el tamaño del archivo, era reacio a hacer un pase inicial solo para contar las líneas, pero parece ser la forma más fácil y eficiente de resolver el problema de la memoria. –

+1

Hace un tiempo, un compañero de trabajo hizo una pregunta similar, y se me ocurrió otra posibilidad que podría salvarte del pase inicial. Si conoce el tamaño aproximado de un "elemento" en el archivo, puede dividirlo en el tamaño del archivo. Agregue un relleno para mayor seguridad, y luego puede escribir en toda la memoria. Para ocultar el extra, sin inicializar, puede usar una vista de solo los elementos con datos. Deberás asegurarte de que no pases por alto. No es perfecto, pero si las lecturas de sus archivos son lentas y sus datos se presentan de manera consistente, podría funcionar. – AFoglia

2

¿Ha intentado utilizar el archivo memmap? Puede iterar a través de su archivo de entrada (en fragmentos si es posible) y convertir los datos entrantes e insertarlos como filas en una matriz numpy mapeada en memoria. La desventaja es que se incurre en más E/S de disco en caso de que no haya suficiente memoria principal y que se necesite paginación desde el intercambio.

Ver: http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

Otra alternativa es PyTables. Deberá construir una tabla especial tipo sql, pero es bastante simple. De hecho, proporciona persistencia de disco transparente (serialización automatizada) y organización jerárquica para sus datos. También limita la cantidad de memoria principal utilizada.

Ver: www.pytables.org/moin/HowToUse

mejor de las suertes!

0

El problema es esencialmente el archivo de texto. Cuando sus datos de entrada se almacenan de una forma más avanzada, se pueden evitar tales problemas. Tome por ejemplo un vistazo al h5py project. Vale la pena primero convertir tus datos a archivos HDF5 y luego ejecutar scripts de análisis en los archivos HDF5.

Cuestiones relacionadas