Как хешировать большой объект (набор данных) в Python? - PullRequest
25 голосов
/ 30 апреля 2009

Я хотел бы рассчитать хеш класса Python, содержащий набор данных для машинного обучения. Хеш предназначен для кэширования, поэтому я думал о md5 или sha1. Проблема в том, что большая часть данных хранится в массивах NumPy; они не предоставляют __hash__() члена. В настоящее время я делаю pickle.dumps() для каждого члена и вычисляю хеш на основе этих строк. Однако я нашел следующие ссылки, указывающие, что один и тот же объект может привести к различным строкам сериализации:

Каков наилучший метод для вычисления хэша для класса Python, содержащего массивы Numpy?

Ответы [ 7 ]

27 голосов
/ 30 апреля 2009

Благодаря Джону Монтгомери, я думаю, что нашел решение, и думаю, что оно требует меньше затрат, чем преобразование каждого числа в огромных массивах в строки:

Я могу создать байтовый вид массивов и использовать их для обновления хэша. И почему-то это дает тот же дайджест, что и прямое обновление с использованием массива:

>>> 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'
3 голосов
/ 29 марта 2011

Существует пакет для запоминания функций, использующих в качестве входных данных числовые массивы joblib . Нашел из этого вопроса.

3 голосов
/ 30 апреля 2009

Какой формат данных в массивах? Не могли бы вы просто перебрать массивы, преобразовать их в строку (с помощью некоторых воспроизводимых средств), а затем передать это в ваш хеш через обновление?

, например

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

Не забывайте, однако, что массивы numpy не будут обеспечивать __hash__(), потому что они изменчивы. Поэтому будьте осторожны, чтобы не изменять массивы после того, как вы вычислили ваш хэш (поскольку он больше не будет прежним).

2 голосов
/ 28 января 2016

Используя Numpy 1.10.1 и python 2.7.6, теперь вы можете просто хэшировать массивы numpy с помощью hashlib, если массив является C-смежным (используйте numpy.ascontiguousarray(), если нет), например,

>>> h = hashlib.md5()
>>> arr = numpy.arange(101)
>>> h.update(arr)
>>> print(h.hexdigest())
e62b430ff0f714181a18ea1a821b0918
2 голосов
/ 28 марта 2011

Вот как я это делаю в кувшине (git HEAD на момент ответа):

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)

Причина в том, что e.data доступен только для некоторых массивов (смежных массивов). То же самое с a.view(np.uint8) (который завершается ошибкой неописательного типа, если массив не является смежным).

1 голос
/ 18 октября 2013

Самым быстрым по некоторому краю является:

хэш (ИТЭР (а))

a - нудистский ndarray.

Очевидно, что не безопасное хеширование, но оно должно быть хорошо для кэширования и т. Д.

1 голос
/ 22 августа 2009

array.data всегда является хэшируемой, потому что это буферный объект. легко :) (если вы не заботитесь о разнице между массивами различной формы с точно такими же данными и т. д. (т. е. это подходит, если фигура, метеорология и другие «параметры» массива также не должны быть включены в хеш)

...