valores una renombrar reemplazar normalizar datos data columnas columna borrar agregar python hash numpy sha1 pickle

una - Cómo hash un objeto grande(conjunto de datos) en Python?



reemplazar valores pandas (7)

Me gustaría calcular un hash de una clase Python que contenga un conjunto de datos para Machine Learning. El hash está destinado a ser utilizado para el almacenamiento en caché, por lo que estaba pensando en md5 o sha1 . El problema es que la mayoría de los datos se almacenan en matrices NumPy; estos no proporcionan un __hash__() . Actualmente hago un pickle.dumps() para cada miembro y calculo un hash basado en estas cadenas. Sin embargo, encontré los siguientes enlaces que indican que el mismo objeto podría conducir a diferentes cadenas de serialización:

¿Cuál sería el mejor método para calcular un hash para una clase Python que contiene matrices Numpy?


¿Cuál es el formato de los datos en las matrices? ¿No podría simplemente iterar a través de las matrices, convertirlas en una cadena (a través de algún medio reproducible) y luego alimentar eso en su hash a través de la actualización?

p.ej

import hashlib m = hashlib.md5() # or sha1 etc for value in array: # array contains the data m.update(str(value))

No olvides que las matrices numpy no proporcionarán __hash__() porque son mutables. Así que tenga cuidado de no modificar las matrices después de calcular su hash (ya que ya no será el mismo).


Así es como lo hago en jug (git HEAD en el momento de esta respuesta):

e = some_array_object M = hashlib.md5() M.update(''np.ndarray'') M.update(pickle.dumps(e.dtype)) M.update(pickle.dumps(e.shape)) try: buffer = e.data M.update(buffer) except: M.update(e.copy().data)

La razón es que e.data solo está disponible para algunas matrices (matrices contiguas). Lo mismo con a.view(np.uint8) (que falla con un error de tipo no descriptivo si la matriz no es contigua).


El más rápido por algún margen parece ser:

hash (iter (a))

a es un ndarray numpy.

Obviamente no es hash seguro, pero debería ser bueno para el almacenamiento en caché, etc.


Gracias a John Montgomery creo que he encontrado una solución, y creo que tiene menos gastos generales que convertir cada número en matrices posiblemente enormes en cadenas:

Puedo crear una vista de bytes de las matrices y usarlas para actualizar el hash. Y de alguna manera esto parece dar el mismo resumen que actualizar directamente usando la matriz:

>>> import hashlib >>> import numpy >>> a = numpy.random.rand(10, 100) >>> b = a.view(numpy.uint8) >>> print a.dtype, b.dtype # a and b have a different data type float64 uint8 >>> hashlib.sha1(a).hexdigest() # byte view sha1 ''794de7b1316b38d989a9040e6e26b9256ca3b5eb'' >>> hashlib.sha1(b).hexdigest() # array sha1 ''794de7b1316b38d989a9040e6e26b9256ca3b5eb''


Hay un paquete para memorizar funciones que usan matrices numpy como entradas joblib . Encontrado a partir de this pregunta.


Usando Numpy 1.10.1 y python 2.7.6, ahora puedes simplemente numerar matrices usando hashlib si la matriz es C-contigua (usa numpy.ascontiguousarray() si no), por ej.

>>> h = hashlib.md5() >>> arr = numpy.arange(101) >>> h.update(arr) >>> print(h.hexdigest()) e62b430ff0f714181a18ea1a821b0918


array.data siempre es hashable, porque es un objeto buffer. fácil :) (a menos que te importe la diferencia entre matrices de formas diferentes con los mismos datos exactos, etc. (es decir, esto es adecuado a menos que la forma, el byteorizador y otros "parámetros" de la matriz también figuren en el hash)