2009-04-30 7 views
25

Je voudrais calculer un hachage d'une classe Python contenant un ensemble de données pour l'apprentissage automatique. Le hachage est destiné à être utilisé pour la mise en cache, donc je pensais à md5 ou sha1. Le problème est que la plupart des données sont stockées dans des tableaux NumPy; ceux-ci ne fournissent pas un membre __hash__(). Actuellement, je fais un pickle.dumps() pour chaque membre et de calculer un hachage basé sur ces chaînes. Cependant, j'ai trouvé les liens suivants indiquant que le même objet pourrait conduire à différentes chaînes de sérialisation:Comment hacher un grand objet (ensemble de données) en Python?

Quelle serait la meilleure méthode pour calculer un hachage pour une classe Python contenant des tableaux Numpy?

+0

Pas beaucoup d'un programmeur python chevronné mais, serait la sérialisation de l'objet et le hachage qui fonctionnent? – Louis

Répondre

3

Quel est le format des données dans les baies? Ne pourriez-vous pas itérer à travers les tableaux, les convertir en une chaîne (via des moyens reproductibles) et ensuite nourrir dans votre hachage via la mise à jour?

par exemple.

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

Ne pas oublier cependant que les tableaux de numpy ne fourniront pas __hash__() parce qu'ils sont mutables. Veillez donc à ne pas modifier les tableaux après avoir calculé votre hachage (car il ne sera plus le même).

+0

Merci, votre message m'a aidé à résoudre ce problème. Voir ci-dessous ... –

27

Merci à John Montgomery Je pense avoir trouvé une solution, et je pense qu'il a moins de frais généraux que la conversion chaque numéro peut-être énormes tableaux à cordes:

Je peux créer un octet vue des tableaux et utilisez-les pour mettre à jour le hachage. Et en quelque sorte, cela semble donner le même que la mise à jour directement digérer à l'aide du tableau:

>>> 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' 
+0

Serez-vous capable de recréer l'objet à partir du cache avec cette technique? Il semble que vous ne pourrez obtenir un tableau de type uint8 (sacrifiant la précision dans votre tableau). – tgray

+0

En utilisant la solution de John Montgomery, il semblerait que vous récupériez un tableau float64. – tgray

+0

@tgray: Parfois, peu importe la précision. Les données expérimentales, en particulier les plus grandes, ont tendance à avoir de grandes incertitudes de toute façon. Évidemment, cela dépend du contexte, mais la règle générale est que la double précision est importante pour le calcul, pas pour stocker les données ou la réponse finale. –

1

array.data est toujours hashable, car il est un objet de mémoire tampon. facile :) (sauf si vous vous souciez de la différence entre les tableaux de formes différentes avec exactement les mêmes données, etc. (c'est-à-dire que la forme, l'octet et les autres paramètres du tableau doivent aussi figurer dans le hash)

+1

array.data n'est pas compatible avec numpy 1.6.2 et python 2.7 – yoavram

2

Voici comment je le fais dans jug (git HEAD au moment de cette réponse).

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 raison est que e.data est disponible uniquement pour certains tableaux (tableaux contigus) même chose avec a.view(np.uint8) (qui échoue avec une erreur de type non descriptif si le tableau n'est pas contigu.)

3

s un paquet pour mémoriser des fonctions utilisant des tableaux numpy comme entrées joblib. Trouvé à partir de this question.

1

le plus rapide par une certaine marge semble être:

hachage (iter (a))

a est un ndarray numpy.

Évidemment pas sûr hash, mais il devrait être bon pour la mise en cache, etc.

+0

Sous python 3.3+, vous n'aurez pas les mêmes valeurs de hachage sur les différentes exécutions de python, en raison des améliorations de sécurité. – xioxox

1

En utilisant Numpy 1.10.1 et python 2.7.6, vous pouvez simplement hash des tableaux en utilisant numpy hashlib si le tableau est C contiguë (utilisez numpy.ascontiguousarray() sinon), par exemple

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