Подтвердить что ты не робот

Как хешировать большой объект (набор данных) в Python?

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

например.

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

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

Ответ 3

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

Ответ 4

Вот как я это делаю в jug (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) (который не работает с ошибкой без описательного типа, если массив не является смежным).

Ответ 5

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

Ответ 6

Самый быстрый с помощью некоторого запаса:

  

хэш (ITER (а))

  

a - это numpy ndarray.

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

Ответ 7

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

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