Numpy поэлементно в работе

#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) для ясности