如果你要调用的距离函数多在您执行程序的一次执行期间,您可以通过使用预计算的位计数表获得一些速度。这里的(另一个)版本的汉明距离函数:
# _nbits[k] is the number of 1s in the binary representation of k for 0 <= k < 256.
_nbits = np.array(
[0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3,
4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4,
4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2,
3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,
4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4,
5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,
3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5,
5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6,
7, 7, 8], dtype=np.uint8)
def hamming_distance1(a, b):
c = np.bitwise_xor(a, b)
n = _nbits[c].sum()
return n
在下面,a
和b
在这个问题评论给定长度32的Python列表。 divakar_hamming_distance()
和divakar_hamming_distance_v2()
来自@ Divakar的回答。
这里有定时@ Divakar的功能:
In [116]: %timeit divakar_hamming_distance(a, b)
The slowest run took 5.57 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 11.3 µs per loop
In [117]: %timeit divakar_hamming_distance_v2(a, b)
The slowest run took 5.35 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 10.3 µs per loop
hamming_distance1(a, b)
是快了一点:
In [118]: %timeit hamming_distance1(a, b)
The slowest run took 6.04 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 7.42 µs per loop
在我的电脑,初始化_nbits
大约需要11微秒,所以没有优势如果您只调用一次函数,则使用hamming_distance1
。如果你三次或更多次称呼它,则表现有净增益。
如果输入已经numpy的阵列,所有的功能都显著快:
In [119]: aa = np.array(a)
In [120]: bb = np.array(b)
In [121]: %timeit divakar_hamming_distance_v2(aa, bb)
The slowest run took 8.22 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.72 µs per loop
In [122]: %timeit hamming_distance1(aa, bb)
The slowest run took 12.67 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 2.77 µs per loop
当然,如果你总是这样,你计算的汉明距离之前,做转换的时候一定要包括在总体时间中。但是,如果您编写生成a
和b
的代码以便早日利用numpy,则在计算海明距离时,可能已将它们作为numpy阵列。
(I也试验了一下与预先计算的汉明距离的8个值之间的2-d阵列 - 具有形状(256阵列,256) - 但初始化成本较高和性能增益小。)
那不'0 + 1'代替因为254是除了在一个位全为1,而255是全1? – Divakar
大概只需要一个标准的popcount配方,在阵列上播放它,然后对结果进行求和。您可以通过将数组的缓冲区视为更大的dtype来获得加速。 – user2357112
@Divakar这是我的错误。接得好。样本数据中的数字更新为240。 –