una tutorial transpuesta multiplicar matriz matrices funciones español elementos ejemplos arreglos array agregar python json numpy apache-storm

python - transpuesta - numpy tutorial español pdf



¿Cómo puedo serializar una matriz numpy mientras preservo las dimensiones de la matriz? (7)

numpy.array.tostring no parece conservar información sobre las dimensiones de la matriz (consulte esta pregunta ), lo que requiere que el usuario numpy.array.reshape una llamada a numpy.array.reshape .

¿Hay alguna manera de serializar una matriz numpy a formato JSON mientras se conserva esta información?

Nota: Las matrices pueden contener ints, flotadores o bools. Es razonable esperar una matriz transpuesta.

Nota 2: esto se está haciendo con la intención de pasar la matriz numpy a través de una topología Storm utilizando streamparse, en caso de que dicha información sea relevante.


Encontré el código en Msgpack-numpy útil. https://github.com/lebedov/msgpack-numpy/blob/master/msgpack_numpy.py

Modifiqué ligeramente el dictado serializado y agregué codificación base64 para reducir el tamaño serializado.

Al utilizar la misma interfaz que json (que proporciona carga (s), volcado (s)), puede proporcionar un reemplazo directo para la serialización de json.

Esta misma lógica se puede ampliar para agregar cualquier serialización no trivial automática, como los objetos de fecha y hora.

EDITAR He escrito un analizador genérico, modular, que hace esto y más. https://github.com/someones/jaweson

Mi código es el siguiente:

np_json.py

from json import * import json import numpy as np import base64 def to_json(obj): if isinstance(obj, (np.ndarray, np.generic)): if isinstance(obj, np.ndarray): return { ''__ndarray__'': base64.b64encode(obj.tostring()), ''dtype'': obj.dtype.str, ''shape'': obj.shape, } elif isinstance(obj, (np.bool_, np.number)): return { ''__npgeneric__'': base64.b64encode(obj.tostring()), ''dtype'': obj.dtype.str, } if isinstance(obj, set): return {''__set__'': list(obj)} if isinstance(obj, tuple): return {''__tuple__'': list(obj)} if isinstance(obj, complex): return {''__complex__'': obj.__repr__()} # Let the base class default method raise the TypeError raise TypeError(''Unable to serialise object of type {}''.format(type(obj))) def from_json(obj): # check for numpy if isinstance(obj, dict): if ''__ndarray__'' in obj: return np.fromstring( base64.b64decode(obj[''__ndarray__'']), dtype=np.dtype(obj[''dtype'']) ).reshape(obj[''shape'']) if ''__npgeneric__'' in obj: return np.fromstring( base64.b64decode(obj[''__npgeneric__'']), dtype=np.dtype(obj[''dtype'']) )[0] if ''__set__'' in obj: return set(obj[''__set__'']) if ''__tuple__'' in obj: return tuple(obj[''__tuple__'']) if ''__complex__'' in obj: return complex(obj[''__complex__'']) return obj # over-write the load(s)/dump(s) functions def load(*args, **kwargs): kwargs[''object_hook''] = from_json return json.load(*args, **kwargs) def loads(*args, **kwargs): kwargs[''object_hook''] = from_json return json.loads(*args, **kwargs) def dump(*args, **kwargs): kwargs[''default''] = to_json return json.dump(*args, **kwargs) def dumps(*args, **kwargs): kwargs[''default''] = to_json return json.dumps(*args, **kwargs)

Deberías poder hacer lo siguiente:

import numpy as np import np_json as json np_data = np.zeros((10,10), dtype=np.float32) new_data = json.loads(json.dumps(np_data)) assert (np_data == new_data).all()


Intente usar numpy.array_repr o numpy.array_str .



Pruebe traitschema https://traitschema.readthedocs.io/en/latest/

"Cree un esquema serializable y con verificación de tipo usando rasgos y Numpy. Un caso de uso típico implica guardar varios arreglos Numpy de formas y tipos diferentes".


Si necesita ser legible para humanos y sabe que esta es una matriz numpy:

import numpy as np; import json; a = np.random.normal(size=(50,120,150)) a_reconstructed = np.asarray(json.loads(json.dumps(a.tolist()))) print np.allclose(a,a_reconstructed) print (a==a_reconstructed).all()

Tal vez no sea el más eficiente, ya que los tamaños de las matrices aumentan de tamaño, pero funcionan para matrices más pequeñas.


pickle.dumps o numpy.save codifican toda la información necesaria para reconstruir una matriz NumPy arbitraria, incluso en presencia de problemas de endianidad, matrices no contiguas o tipos de tuplas extraños. Los problemas de endianness son probablemente los más importantes; no desea que la array([1]) se convierta repentinamente en array([16777216]) porque cargó su matriz en una máquina big-endian. pickle es probablemente la opción más conveniente, aunque save tiene sus propios beneficios, dados en el formato del formato npy .

La opción de pickle :

import pickle a = # some NumPy array serialized = pickle.dumps(a, protocol=0) # protocol 0 is printable ASCII deserialized_a = pickle.loads(serialized)

numpy.save usa un formato binario, y necesita escribir en un archivo, pero puede StringIO con StringIO :

a = # any NumPy array memfile = StringIO.StringIO() numpy.save(memfile, a) memfile.seek(0) serialized = json.dumps(memfile.read().decode(''latin-1'')) # latin-1 maps byte n to unicode code point n

Y para deserializar:

memfile = StringIO.StringIO() memfile.write(json.loads(serialized).encode(''latin-1'')) memfile.seek(0) a = numpy.load(memfile)


EDITAR: Como se puede leer en los comentarios de la pregunta, esta solución trata con matrices numpy "normales" (flotadores, ints, bools ...) y no con matrices estructuradas de tipo múltiple.

Solución para serializar una matriz numpy de cualquier dimensión y tipo de datos

Por lo que sé, no puede simplemente serializar una matriz numpy con cualquier tipo de datos y cualquier dimensión ... pero puede almacenar su tipo de datos, dimensión e información en una representación de lista y luego serializarlos utilizando JSON.

Importaciones necesarias :

import json import base64

Para la codificación que podría usar ( nparray es una matriz numpy de cualquier tipo de datos y cualquier dimensionalidad):

json.dumps([str(nparray.dtype), base64.b64encode(nparray), nparray.shape])

Después de esto, obtiene un volcado JSON (cadena) de sus datos, que contiene una representación de la lista de su tipo y forma de datos, así como los arreglos de datos / contenidos codificados en base64.

Y para decodificar esto funciona ( encStr es la cadena JSON codificada, cargada desde algún lugar):

# get the encoded json dump enc = json.loads(encStr) # build the numpy data type dataType = numpy.dtype(enc[0]) # decode the base64 encoded numpy array data and create a new numpy array with this data & type dataArray = numpy.frombuffer(base64.decodestring(enc[1]), dataType) # if the array had more than one data set it has to be reshaped if len(enc) > 2: dataArray.reshape(enc[2]) # return the reshaped numpy array containing several data sets

Los volcados JSON son eficientes y compatibles entre sí por muchas razones, pero solo tomar JSON conduce a resultados inesperados si desea almacenar y cargar matrices numpy de cualquier tipo y cualquier dimensión .

Esta solución almacena y carga numerosos arreglos independientemente del tipo o dimensión y también la restaura correctamente (tipo de datos, dimensión, ...)

Probé varias soluciones hace algunos meses y esta fue la única solución eficiente y versátil que encontré.