【问题标题】:numpy bitwise_and unable to broadcast argument 1 to output arraynumpy bitwise_and 无法将参数 1 广播到输出数组
【发布时间】:2021-01-07 13:47:09
【问题描述】:

我正在尝试实现矢量化来回答这个问题

Fastest way to get hamming distance for integer array

r = (1 << np.arange(64, dtype=np.uint64))[:, None]
def hamming_distance_v2(a, b):
    t = np.bitwise_xor(a, b)
    p = np.bitwise_and(t, r)
    return np.count_nonzero(p != 0)

我想传递一个二维数组作为第一个参数,例如

a = [[127,255], [127,255]]
b = [127,240]
hamming_distance_v1(a, b) -> [4,4]

如果使用二维数组作为第一个参数,则返回以下错误:

ValueError: unable to broadcast argument 1 to output array

有没有办法在当前实现汉明距离的基础上实现矢量化或其他方法来计算 2d 和 1d 数组之间的距离?

【问题讨论】:

    标签: python numpy vectorization hamming-distance


    【解决方案1】:

    根据问答链接的回答,他们将修改以合并额外的暗淡,如下所示。

    方法#1

    def hamming_distance(a, b):
        r = (1 << np.arange(8))[:,None]
        mask = (a[:,None] & r) != (b & r)
        return mask.sum((1,2))
    

    方法 #2

    def hamming_distance_v2(a, b):
        r = (1 << np.arange(8))[:,None]
        xor = np.bitwise_xor(a[:,None],b)
        mask = (xor & r) != 0
        return mask.sum((1,2))
    

    方法#3

    另一个np.unpackbits -

    def hamming_distance_v3(a, b):
        a = np.asarray(a, dtype=np.uint8)
        b = np.asarray(b, dtype=np.uint8)
        m = np.unpackbits(a,axis=1) != np.unpackbits(b)
        return m.sum(1)
    

    示例运行 -

    In [107]: a
    Out[107]: 
    array([[127, 255],
           [127, 205],
           [227, 255]])
    
    In [108]: b
    Out[108]: array([127, 240])
    
    In [109]: hamming_distance(a, b)
    Out[109]: array([4, 5, 8])
    

    【讨论】:

    • 对于循环数组并使用非向量化比使用那些向量化函数更快,这可能是数组长度的问题吗?
    • @AlexanderKarp 比所有发布的三种方法都快?
    • 比 hamming_distance 和 hamming_distance_v2 更快,hamming_distance_v3 我不能使用因为 np.unpackbits 不能与 uint64 一起使用 pastebin.com/S3rDJmr3 如果 step 是长度,我得到了最好的结果 step = 1 (27s)滑动数组计算卡住了
    • @AlexanderKarp 你能分享循环版本吗?
    • 一些澄清:我有一个源数组和一个目标数组,我想在源数组中找到与目标数组的汉明距离最小的位置。所以有两种方法可以做到:使用 step=1 循环和将源数组滑动到窗口以实现矢量化,两者都有:pastebin.com/fF9K6X1z
    猜你喜欢
    • 1970-01-01
    • 2020-02-11
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多