Как векторизовать операцию между 2D-массивом и другим вектором? - PullRequest
2 голосов
/ 19 января 2020

У меня есть numpy 2D массив, подобный этому:

[[1, 2], [3, 4]]

И отдельный вектор, подобный этому: [5, 6].

Операция в этом случае np.inner, как часть моей более крупной задачи - взять косинусное сходство между каждой строкой двумерного массива и отдельным вектором.

Мой ожидаемый результат - [np.inner([1, 2], [5, 6]), np.inner([3, 4], [5, 6]]. Я могу выполнить sh, используя apply_along_axis, но есть ли способ векторизовать эту операцию и сделать ее более производительной, чем apply_along_axis?

Существует множество ответов на вопросы о том, как векторизовать эти типы. операции между парами строк двух 2D-массивов, но в этой ситуации мне нужно векторизовать операцию между одним 2D-массивом и другим вектором. Я мог бы превратить [5, 6] в [[5, 6], [5, 6]], а затем выполнить векторизацию таким образом, но в больших масштабах мне нужно решение, где я мог бы использовать сам другой вектор в операции, а не превращать его в двумерный массив с кучей строк копии.

Ответы [ 2 ]

3 голосов
/ 19 января 2020
In [6]: A = np.array([[1,2],[3,4]]); x=np.array([5,6])                                           

inner работает с вашим 2d-массивом (правда, его документация немного расплывчата по этому поводу

In [7]: np.inner(A,x)                                                                            
Out[7]: array([17, 39])

Обычно мы используем np.dot для умножения матриц, включая 1d inner:

In [8]: np.dot(A,x)                                                                              
Out[8]: array([17, 39])

или в более новом numpy, операторе @, который также np.matmul.

In [9]: A@x                                                                                      
Out[9]: array([17, 39])

Оба используют суммы last of A со 2-м до последнего из B` (или единственная ось x).

Два внутренних вычисления, которые вы хотите:

In [10]: np.inner(A[0,:],x)                                                                      
Out[10]: 17
In [11]: np.inner(A[1,:],x)                                                                      
Out[11]: 39

A (2, n) широковещательные рассылки с массивом (n,), просто отлично, результат (2, n)

In [12]: A * x                                                                                   
Out[12]: 
array([[ 5, 12],
       [15, 24]])
In [13]: (A * x).sum(axis=1)       # and sum on the `n` axis for inner                                                                 
Out[13]: array([17, 39])

broadcasting имеет эффект повторяющихся строк (или других измерений), но эффективен в вычислительном отношении.

3 голосов
/ 19 января 2020

Звучит так, как будто вам нужно `np.dot '

In [3]: a = np.array([[1, 2], [3, 4]])

In [4]: b = np.array([5, 6])

In [5]: a.dot(b)
Out[5]: array([17, 39])

In [6]: np.inner(a[0], b)
Out[6]: 17

In [7]: np.inner(a[1], b)
Out[7]: 39
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...