我试图为numpy数组实现一些哈希函数,以便在一个大的数组列表中轻松找到它们,但我发现几乎每个哈希函数都需要使用多个操作进行reduce
, for example:
def fnv_hash (arr):
result = FNV_offset_basis
for v in arr.view(dtype = np.uint8):
result *= FNV_prime
result ^= v
return result
在每个循环中对result
变量进行两次操作,我认为在numpy函数中只使用reduce
调用是不可能的(即numpy.ufunc.reduce
)。
我想避免使用基本循环,因为它们不会将numpy数组视为内存区域(速度很慢)而且我不想使用hashlib
函数。此外,使用numpy.vectorize
和类似的转换函数(这只是documentation中所说的for循环)并没有帮助提高性能。
不幸的是我无法使用numba.jit
,因为我正在使用大型数组,我需要在没有安装numba
的群集中运行我的代码。 xxhash
也是如此。
到目前为止,我的解决方案是使用简单的散列函数
def my_hash (arr):
indices = np.arange(arr.shape[0])
return int((arr * ((1 << (indices * 5)) - indices)).sum())
这有点快(这不是实际的功能代码,我在我的脚本中做了一些优化,但我可以向你保证输出是一样的),但它会产生一些不必要的碰撞。
简而言之:我只想使用numpy操作来实现良好的散列函数,因为我的数组和搜索空间非常庞大。
提前致谢。
答案 0 :(得分:0)
由于您的阵列非常庞大,但您没有很多阵列,您是否尝试过散列每个阵列的一部分?例如,即使arr
很大,hash(tuple(arr[:10e5]))
在我的机器上约为60毫秒,并且可能足以区分10k个不同的数组,具体取决于它们的生成方式。
如果这不能解决您的问题,那么您可以为问题提供的任何其他背景信息都会有所帮助。这些数组是如何以及何时生成的?你为什么试图哈希呢?