Leyendo matrices de números fuera de Python

En una pregunta reciente, pregunté sobre la forma más rápida de convertir una matriz numpy grande en una cadena delimitada. Mi motivo para preguntar fue porque quería tomar esa cadena de texto sin formato y transmitirla (a través de HTTP, por ejemplo) a clientes escritos en otros lenguajes de progtwigción. Una cadena de números delimitada es obviamente algo con lo que cualquier progtwig cliente puede trabajar fácilmente. Sin embargo, se sugirió que debido a que la conversión de cadenas es lenta, sería más rápido en el lado de Python hacer la encoding base64 en la matriz y enviarla como binario. Esto es de hecho más rápido.

Mi pregunta ahora es: (1) cómo puedo asegurarme de que mi matriz de números codificados viajará bien a los clientes en diferentes sistemas operativos y hardware, y (2) cómo decodificar los datos binarios en el lado del cliente.

Para (1), mi inclinación es hacer algo como lo siguiente

import numpy as np import base64 x = np.arange(100, dtype=np.float64) base64.b64encode(x.tostring()) 

¿Hay algo más que deba hacer?

Para (2), me encantaría tener un ejemplo en cualquier lenguaje de progtwigción, donde el objective es tomar la gran cantidad de flotadores y convertirlos en una estructura de datos nativa similar. Supongamos que ya hemos realizado la deencoding base64 y tenemos una matriz de bytes, y que también conocemos el tipo de dato, las dimensiones y cualquier otro metadato que será necesario.

Gracias.

Lo que hace el método de secuencia de arrays numpy es básicamente darle un volcado de la memoria utilizada por los datos de la matriz (no el envoltorio de objetos para Python, sino solo los datos de la matriz). Esto es similar al módulo struct stdlib. La encoding Base64 que codifica esa cadena y su transmisión debe ser lo suficientemente buena, aunque es posible que también deba enviar el tipo de datos real utilizado, así como las dimensiones si se trata de una matriz multidimensional, ya que no podrá decirles solo eso. a partir de los datos.

Por otro lado, cómo leer los datos depende un poco del idioma. La mayoría de los idiomas tienen una forma de abordar un bloque de memoria como un tipo particular de matriz. Por ejemplo, en C, podría basar la deencoding 64 de la cadena, asignarla a (en el caso de su ejemplo) un float64 * e indizar. Esto no le brinda ninguna de las funciones y salvaguardas integradas y otras operaciones que tienen muchos arrays en Python, pero eso se debe a que C es un lenguaje muy diferente al respecto.

Realmente debería mirar OPeNDAP para simplificar todos los aspectos de las redes de datos científicos. Para Python, echa un vistazo a Pydap .

Puede almacenar directamente sus arreglos NumPy en formato HDF5 a través de h5py (o NetCDF), y luego transmitir los datos a los clientes a través de HTTP usando OPeNDAP.

Recomiendo usar un formato de datos existente para el intercambio de datos / arreglos científicos, como NetCDF o HDF . En Python, puedes usar la biblioteca PyNIO que tiene muchos enlaces, y hay varias bibliotecas para otros idiomas. Ambos formatos están diseñados para manejar grandes volúmenes de datos y se ocupan del idioma, problemas de representación de la máquina, etc. También funcionan bien con el paso de mensajes, por ejemplo, en computación en paralelo, por lo que sospecho que su caso de uso está satisfecho.

Para algo un poco más liviano que HDF (aunque es cierto que también es más ad-hoc), también puedes usar JSON:

 import json import numpy as np x = np.arange(100, dtype=np.float64) print json.dumps(dict(data=x.tostring(), shape=x.shape, dtype=str(x.dtype))) 

Esto liberaría a sus clientes de la necesidad de instalar envoltorios HDF, a costa de tener que lidiar con un protocolo no estándar para el intercambio de datos (¡y posiblemente también necesitar instalar enlaces JSON!).

La compensación estaría en tus manos para evaluar tu situación.