简体   繁体   English

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

[英]Populate numpy matrix from the difference of two vectors

Is it possible to construct a numpy matrix from a function? 是否有可能从函数构造一个numpy矩阵? In this case specifically the function is the absolute difference of two vectors: S[i,j] = abs(A[i] - B[j]) . 在这种情况下,具体地,该函数是两个向量的绝对差: S[i,j] = abs(A[i] - B[j]) A minimal working example that uses regular python: 一个使用常规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.]]

It would be nice to have a construction that looks something like: 有一个看起来像这样的结构会很好:

def build_matrix(shape, input_function, *args)

where I can pass an input function with it's arguments and retain the speed advantage of numpy. 我可以用它的参数传递一个输入函数,并保持numpy的速度优势。

In addition to what @JoshAdel has suggested, you can also use the outer method of any numpy ufunc to do the broadcasting in the case of two arrays. 除了什么@JoshAdel曾建议,您也可以使用outer方法的任何numpy的的ufunc做广播两个数组中的情况。

In this case, you just want np.subtract.outer(A, B) (Or, rather, the absolute value of it). 在这种情况下,你只需要np.subtract.outer(A, B) (或者更确切地说,它的绝对值)。

While either one is fairly readable for this example, in some cases broadcasting is more useful, while in others using ufunc methods is cleaner. 虽然这个例子中任何一个都是可读的,但在某些情况下广播更有用,而在其他情况下使用ufunc方法更清晰。

Either way, it's useful to know both tricks. 无论哪种方式,了解这两个技巧都很有用。

Eg 例如

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)

Basically, you can use outer , accumulate , reduce , and reduceat with any numpy ufunc such as subtract , multiply , divide , or even things like logical_and , etc. 基本上,你可以使用outeraccumulatereducereduceat任何numpy的ufuncsubtractmultiplydivide ,甚至喜欢的东西logical_and等。

For example, np.cumsum is equivalent to np.add.accumulate . 例如, np.cumsum等同于np.add.accumulate This means you could implement something like a cumdiv by np.divide.accumulate if you even needed to. 这意味着如果你需要,你可以通过np.divide.accumulate实现像cumdiv这样的东西。

I recommend taking a look into numpy's broadcasting capabilities: 我建议看看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 http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html

Then you could simply write your function as: 然后您可以简单地将您的函数编写为:

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 should also be considerably faster than your solution for larger arrays. 这也应该比大型阵列的解决方案快得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM