numpy bitwise_and не может передать аргумент 1 в выходной массив

Я пытаюсь реализовать векторизацию для ответа на этот вопрос

Самый быстрый способ получить расстояние Хэмминга для целочисленного массива

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)

Я хочу передать 2d-массив в качестве первого параметра, например

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

Если в качестве первого аргумента используется массив 2d, возвращается следующая ошибка:

ValueError: unable to broadcast argument 1 to output array

Есть ли способ реализовать векторизацию для текущей реализации расстояния Хэмминга или какие-то другие способы подсчета этого расстояния между массивами 2d и 1d?


person Alexander Karp    schedule 21.09.2020    source источник


Ответы (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])
person Divakar    schedule 21.09.2020
comment
Поскольку цикл по массиву и использование не векторизованного быстрее, чем использование этих векторизованных функций, может ли это быть проблемой с длиной массива? - person Alexander Karp; 21.09.2020
comment
@AlexanderKarp Быстрее, чем все три опубликованных подхода? - person Divakar; 21.09.2020
comment
быстрее, чем hamming_distance и hamming_distance_v2, hamming_distance_v3 я не могу использовать, потому что np.unpackbits нельзя использовать с uint64 pastebin.com/S3rDJmr3 Я получил лучший результат с шагом = 1 (27 с), если шаг равен длине скользящего массива, вычисление застревает - person Alexander Karp; 22.09.2020
comment
@AlexanderKarp Можете ли вы поделиться версией цикла? - person Divakar; 22.09.2020
comment
Некоторое пояснение: у меня есть исходный массив и целевой массив, и я хочу найти место в исходном массиве, где расстояние Хэмминга с целевым массивом минимально возможно. Таким образом, есть два подхода к этому: для цикла с шагом = 1 и перемещения исходного массива в окна для реализации векторизации, есть оба из них: pastebin.com/fF9K6X1z - person Alexander Karp; 22.09.2020
comment
Циклическая версия с numba для массива a формы (2095250,) и массива b (250,) выполняется в течение 20 секунд, векторизованная версия с оконным массивом a (2095001, 250) и b (250,) были убиты моей ОС с кодом выхода 137 :) - person Alexander Karp; 22.09.2020