如何在Python中哈希大对象(数据集)?
我想计算一个包含机器学习数据集的Python类的哈希值。这个哈希值是用来缓存的,所以我在考虑使用md5
或sha1
。问题是,大部分数据存储在NumPy数组中,而这些数组没有提供__hash__()
这个方法。目前,我是对每个成员使用pickle.dumps()
,然后根据这些字符串计算哈希值。不过,我发现了一些链接,指出同一个对象可能会生成不同的序列化字符串:
那么,计算一个包含NumPy数组的Python类的哈希值,最好的方法是什么呢?
7 个回答
3
这些数组里的数据格式是什么样的呢?你难道不能遍历这些数组,把它们转换成字符串(用某种可重复的方法),然后通过更新的方式把这个字符串放进你的哈希里吗?
比如说:
import hashlib
m = hashlib.md5() # or sha1 etc
for value in array: # array contains the data
m.update(str(value))
不过要记住,numpy数组是可变的,所以它们不会提供__hash__()
这个功能。所以在你计算出哈希值之后,要小心不要修改这些数组,因为那样哈希值就不再是原来的了。
34
感谢John Montgomery的帮助,我觉得我找到了一个解决办法,而且这个办法的开销比把可能非常大的数组里的每个数字都转换成字符串要小:
我可以创建一个字节视图(byte-view)来处理这些数组,然后用这个视图来更新哈希值。奇怪的是,这样做似乎能得到和直接用数组更新时一样的结果:
>>> 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'