使用采样数据时,CRC32功能如何工作?

And*_*256 2 python hash hex

我想问您有关Python中以下简短函数的解释。

from zlib import crc32

def test_set_check(identifier, test_ratio):
    return crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2**32
Run Code Online (Sandbox Code Playgroud)

上述功能应与以下功能相同:

import hashlib

def test_set_check(identifier, test_ratio, hash=hashlib.md5):
    return hash(np.int64(identifier)).digest()[-1] < 256 * test_ratio
Run Code Online (Sandbox Code Playgroud)

这两个函数都应用于数据采样(选择表中的某些行)。例如,如果test_ratio为0.2,则表示我要采样20%的数据,该值小于或等于51(256的20%)。我了解第二个功能的工作原理,但我不了解第一个功能。您能告诉我第一个功能吗?我不明白以下部分:crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2**32

Mar*_*ers 6

crc32函数输出一个无符号的32位数字,并且代码测试CRC值是否低于test_ratio与最大32位数字的乘积。

所述& 0xffffffff掩模不仅存在于确保与Python 2和3的相容性。在Python 2中,相同的函数可以返回一个有符号整数,范围为-(2 ^ 31)到(2 ^ 31)-1,并用0xffffffffmask掩码将其标准化为有符号整数。

因此,基本上,任何一个版本都将标识符转换为整数,并且使用哈希值使该整数合理地均匀分布在范围内;对于MD5哈希,它是使值介于0到255之间的最后一个字节,对于CRC32校验和,该值介于0和(2 ^ 32)-1之间。然后将该整数与整个范围进行比较;如果它低于test_ratio * maximum截止点,则认为已选择。

您也可以使用随机函数,但是每次选择样本时,您都会得到不同的输入子集。通过对标识符进行哈希处理,可以生成一致的子集。两种方法之间的区别在于它们将产生不同的子集,因此您可以将两者一起使用以从同一输入中选择多个独立的子集。

比较:

>>> 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
Run Code Online (Sandbox Code Playgroud)

因此,这两种不同的方法会产生不同的输出,但是只要CRC32和MD5哈希产生合理分布均匀的哈希值,那么两种方法都可以给您20%的合理采样率。