Заполните пустую матрицу из разности двух векторов - PullRequest
9 голосов
/ 14 марта 2012

Можно ли построить матрицу numpy из функции?В данном случае конкретно функция представляет собой абсолютную разницу двух векторов: S[i,j] = abs(A[i] - B[j]).Минимальный рабочий пример, использующий обычный python:

import numpy as np

A = np.array([1,3,6])
B = np.array([2,4,6])
S = np.zeros((3,3))

for i,x in enumerate(A):
    for j,y in enumerate(B):
        S[i,j] = abs(x-y)

Giving:

[[ 1.  3.  5.]
 [ 1.  1.  3.]
 [ 4.  2.  0.]]

Было бы неплохо иметь конструкцию, которая выглядит примерно так:

def build_matrix(shape, input_function, *args)

где я могу передать входную функцию с ее аргументами и сохранить преимущество скорости в numpy.

Ответы [ 2 ]

16 голосов
/ 14 марта 2012

В дополнение к тому, что предложил @JoshAdel, вы также можете использовать outer метод любого numpy ufunc для трансляции в случае двух массивов.

В этом случае вам просто нужно np.subtract.outer(A, B) (или, скорее, его абсолютное значение).

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

В любом случае, полезно знать оба трюка.

Например,

import numpy as np

A = np.array([1,3,6])
B = np.array([2,4,6])

diff = np.subtract.outer(A, B)
result = np.abs(diff)

В основном вы можете использовать outer, accumulate, reduce иreduceat с любыми значениями ufunc, такими как subtract, multiply, divide или даже такими вещами, как logical_and и т. Д.

Например, np.cumsum эквивалентно np.add.accumulate.Это означает, что вы можете реализовать что-то вроде cumdiv на np.divide.accumulate, если вам даже нужно.

12 голосов
/ 14 марта 2012

Я рекомендую взглянуть на возможности вещания numpy:

In [6]: np.abs(A[:,np.newaxis] - B)
Out[6]: 
array([[1, 3, 5],
       [1, 1, 3],
       [4, 2, 0]])

http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html

Тогда вы можете просто написать свою функцию как:

In [7]: def build_matrix(func,args):
   ...:     return func(*args)
   ...: 

In [8]: def f1(A,B):
   ...:     return np.abs(A[:,np.newaxis] - B)
   ...: 

In [9]: build_matrix(f1,(A,B))
Out[9]: 
array([[1, 3, 5],
       [1, 1, 3],
       [4, 2, 0]])

Thisтакже должен быть значительно быстрее, чем ваше решение для больших массивов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...