我想问你关于Python中以下短函数的解释。
from zlib import crc32
def test_set_check(identifier, test_ratio):
return crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2**32
上述函数应与以下函数相同:
import hashlib
def test_set_check(identifier, test_ratio, hash=hashlib.md5):
return hash(np.int64(identifier)).digest()[-1] < 256 * test_ratio
这两个函数都应该用于数据采样(选择表中的某些行)。例如,如果test_ratio
是 0.2 那么这意味着我想要采样 20% 的数据,该值低于或等于 51(~256 的 20%)。我理解第二个函数是如何工作的,但我不明白第一个函数。你能给我解释一下第一个功能吗?我不明白以下部分:crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2**32
The crc32
函数输出一个无符号的 32 位数字,代码测试 CRC 值是否低于 test_ratio 乘以最大 32 位数字。
The & 0xffffffff
面具只是为了确保与 Python 2 和 3 的兼容性 https://docs.python.org/3/library/zlib.html#zlib.crc32。在 Python 2 中,相同的函数可以返回signed整数,范围从 -(2^31) 到 (2^31) - 1,用0xffffffff
mask 将值标准化为带符号的值。
所以基本上,任一版本都将标识符转换为整数,并使用哈希使该整数在一个范围内合理均匀分布;对于 MD5 哈希值来说,最后一个字节的值介于 0 和 255 之间;对于 CRC32 校验和,该值介于 0 和 (2^32)-1 之间。然后将该整数与整个范围进行比较;如果低于test_ratio * maximum
截止点被视为已选择。
您还可以使用随机函数,但是每次选择样本时您都会得到不同的输入子集;通过对标识符进行哈希处理,您可以生成持续的子集。这两种方法之间的区别在于它们会生成不同的子集,因此您可以同时使用这两种方法从同一输入中选取多个独立的子集。
Compare:
>>> import numpy as np
>>> from zlib import crc32
>>> from hashlib import md5
>>> import random
>>> identifier = np.int64(random.randrange(2**63))
>>> md5(identifier).digest()[-1]
243
>>> md5(identifier).digest()[-1] / 256 # as a ratio of the full range
0.94921875
>>> crc32(identifier)
4276259108
>>> crc32(identifier) / (2 ** 32) # ratio again
0.9956441605463624
>>> identifier = np.int64(random.randrange(2**63)) # different id to compare
>>> md5(identifier).digest()[-1] / 256 # as a ratio of the full range
0.83203125
>>> crc32(identifier) / (2 ** 32) # ratio again
0.10733163682743907
因此两种不同的方法会产生不同的输出,但只要 CRC32 和 MD5 哈希值合理地产生均匀分布哈希值,那么两者都会给你 20% 的采样率。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)