从两个向量的差异中填充numpy矩阵

Hoo*_*ked 11 python numpy

是否可以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)
Run Code Online (Sandbox Code Playgroud)

赠送:

[[ 1.  3.  5.]
 [ 1.  1.  3.]
 [ 4.  2.  0.]]
Run Code Online (Sandbox Code Playgroud)

有一个看起来像这样的结构会很好:

def build_matrix(shape, input_function, *args)
Run Code Online (Sandbox Code Playgroud)

我可以用它的参数传递一个输入函数,并保持numpy的速度优势.

Joe*_*ton 17

除了@JoshAdel所建议的,你还可以使用任何numpy 的outer方法ufunc在两个数组的情况下进行广播.

在这种情况下,您只需要np.subtract.outer(A, B) (或者更确切地说,它的绝对值).

虽然这个例子中任何一个都是可读的,但在某些情况下广播更有用,而在其他情况下使用ufunc方法更清晰.

无论哪种方式,了解这两个技巧都很有用.

例如

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)
Run Code Online (Sandbox Code Playgroud)

基本上,你可以使用outer,accumulate,reduce,和reduceat任何numpy的ufunc,例如subtract,multiply,divide,甚至之类的东西logical_and,等等.

例如,np.cumsum相当于np.add.accumulate.这意味着如果你需要,你可以实现类似于cumdivby的东西np.divide.accumulate.


Jos*_*del 14

我建议看看numpy的广播功能:

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

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]])
Run Code Online (Sandbox Code Playgroud)

这也应该比大型阵列的解决方案快得多.

  • 为了避免创建一个保持差异的中间数组[`numpexpr`](https://code.google.com/p/numexpr/),可以使用:`c = a [:,None]; result = numexpr.evaluate("abs(c - b)")` (2认同)