#python #performance #numpy #vectorization #elementwise-operations
#python #Производительность #numpy #векторизация #поэлементные операции
Вопрос:
Предположим, у меня есть вектор-столбец y длиной n, и у меня есть матрица X размером n * m. Я хочу проверить для каждого элемента i в y, находится ли элемент в соответствующей строке в X. Какой наиболее эффективный способ сделать это?
Например:
y = [1,2,3,4].T
и
X =[[1, 2, 3],[3, 4, 5],[4, 3, 2],[2, 2, 2]]
Тогда результат должен быть
[1, 0, 1, 0] or [True, False, True, False]
что когда-либо было проще.
Конечно, мы можем использовать цикл for для перебора как y, так и X, но есть ли какой-либо более эффективный способ сделать это?
Комментарии:
1. Вы уверены, что не хотите, чтобы результат был
np.array([True, False, True, False])
?
Ответ №1:
Векторизованный подход с использованием broadcasting
—
((X == y[:,None]).any(1)).astype(int)
Пример запуска —
In [41]: X # Input 1
Out[41]:
array([[1, 2, 3],
[3, 4, 5],
[4, 3, 2],
[2, 2, 2]])
In [42]: y # Input 2
Out[42]: array([1, 2, 3, 4])
In [43]: X == y[:,None] # Broadcasted comparison
Out[43]:
array([[ True, False, False],
[False, False, False],
[False, True, False],
[False, False, False]], dtype=bool)
In [44]: (X == y[:,None]).any(1) # Check for any match along each row
Out[44]: array([ True, False, True, False], dtype=bool)
In [45]: ((X == y[:,None]).any(1)).astype(int) # Convert to 1s and 0s
Out[45]: array([1, 0, 1, 0])
Комментарии:
1. Я бы сказал, что
any(1)
должно быть написано.any(axis=1)
для ясности