numpy 如何在Python中散列一个大对象(数据集)?

fslejnso  于 2023-02-04  发布在  Python
关注(0)|答案(7)|浏览(128)

我想计算一个Python类的散列,这个类包含一个机器学习用的数据集,这个散列是用来缓存的,所以我想到了md5或者sha1,问题是大部分数据都存储在NumPy数组中;这些不提供__hash__()成员。目前我为每个成员执行pickle.dumps()并基于这些字符串计算散列。但是,我发现以下链接表明同一对象可能导致不同的序列化字符串:

对于包含Numpy数组的Python类,计算哈希的最佳方法是什么?

kx1ctssn

kx1ctssn1#

多亏了John蒙哥马利,我想我找到了一个解决方案,而且我认为它比将可能 * 巨大 * 的数组中的每个数字转换为字符串的开销要小:
我可以创建一个数组的字节视图,然后用它来更新哈希值,不知怎么的,这看起来和直接用数组更新一样:

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

1yjd4xko2#

数组中数据的格式是什么?你不能只是遍历数组,把它们转换成一个字符串(通过一些可复制的方法),然后通过更新把它馈送到你的散列中吗?
例如:

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

但是不要忘记numpy数组不会提供__hash__(),因为它们是可变的,所以在计算哈希值后不要修改数组(因为它将不再相同)。

q9yhzks0

q9yhzks03#

有一个记忆函数的包,使用numpy数组作为输入joblib。从this问题中找到。

wrrgggsh

wrrgggsh4#

使用Numpy 1.10.1和python 2.7.6,如果numpy数组是C连续的(如果不是,使用numpy.ascontiguousarray()),现在可以使用hashlib简单地散列numpy数组,例如:

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

2admgd595#

下面是我在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)也是如此(如果数组不连续,则会出现非描述性类型错误)。

ff29svar

ff29svar6#

最快的似乎是:

>>> hash(iter(a))

a是一个numpy数组。
显然不是安全的散列,但它应该是好的缓存等。

ebdffaop

ebdffaop7#

array.data 总是可散列的,因为它是一个缓冲区对象。easy:)(除非你关心具有完全相同数据的不同形状的数组之间的差异,等等。(即这是合适的,除非shape,byteorder,和其他数组'参数'也必须计算到散列中)

相关问题