将bsxfun与@times转换为numpy



这是我在Octave中的代码:

sum(bsxfun(@times, X*Y, X), 2)

代码的bsxfun部分产生元素智能乘法,所以我认为numpy.multiply(X*Y, X)可以做到这一点,但我得到了一个异常。当我做了一些研究后,我发现元素乘法在Python数组上不起作用(特别是如果X和Y的类型是"numpy. narray")。所以我想知道是否有人可以解释这一点更多-即类型转换到不同类型的对象工作吗?八度代码可以工作,所以我知道我没有线性代数错误。我猜那是有趣而愚蠢的。乘法实际上并不等同,但我不确定为什么,所以任何解释都会很棒。

我找到了一个网站!它给出了Octave到Matlab函数转换,但在我的情况下似乎没有帮助。

bsxfun在Matlab中代表二进制单例展开,在numpy中它被称为广播,应该自动发生。解决方案将取决于你的X的尺寸,即它是一个行或列向量,但这个答案显示了一种方法:

如何将numpy 2D数组与numpy 1D数组相乘?

我认为这里的问题是广播需要其中一个维度是1,与Matlab不同,numpy似乎区分了1维2元素向量和2维2元素,即形状(2,)和形状(2,1)的矩阵之间的差异,您需要后者进行广播。

对于那些不知道Numpy的人,我认为值得指出的是,Octave(和Matlab的)*运算符(矩阵乘法)的等效是numpy.dot(以及有争议的numpy.outer)。Numpy的*运算符类似于Octave中的bsxfun(@times,...),它本身就是.*的泛化。

在Octave中,当应用bsxfun时,在操作数的"真实"大小的右侧有隐式的单例维度;也就是说,一个n1 x n2 x n3数组可以被认为是n1 x n2 x n3 x 1 x 1 x 1 x...。在Numpy中,隐式的单维在左边;因此,m1 x m2 x m3可以被认为是... x 1 x 1 x m1 x m2 x m3。这在考虑操作数大小时很重要:在Octave中,如果a是2 x 3 x 4, b是2 x 3, bsxfun(@times,a,b)将起作用。在Numpy中,不能将两个这样的数组相乘,但是可以2 x 3 x 43 x 4数组相乘。

最后,Octave中的bsxfun(@times, X*Y, X)可能看起来像numpy.dot(X,Y) * X。仍然有一些陷阱:例如,如果您期望外部乘积(即,在Octave中X是列向量,Y是行向量),您可以使用numpy.outer来代替,或者注意X和Y的形状。

有点晚了,但我想提供一个在python中具有等效bsxfunrepmat的示例。这是我刚刚从Matlab转换到Python的一小段代码numpy:

Matlab:

x =
    -2
    -1
     0
     1
     2
n =
 2
M = repmat(x,1,n+1)
M =
    -2    -2    -2
    -1    -1    -1
     0     0     0
     1     1     1
     2     2     2

M = bsxfun(@power,M,0:n)
M =
     1    -2     4
     1    -1     1
     1     0     0
     1     1     1
     1     2     4

等价于Python:

In [8]: x
Out[8]: 
array([[-2],
       [-1],
       [ 0],
       [ 1],
       [ 2]])
In [9]: n=2
In [11]: M = np.tile(x, (1, n + 1))
In [12]: M
Out[12]: 
array([[-2, -2, -2],
       [-1, -1, -1],
       [ 0,  0,  0],
       [ 1,  1,  1],
       [ 2,  2,  2]])

In [13]:  M = np.apply_along_axis(pow, 1, M, range(n + 1))
In [14]: M
Out[14]: 
array([[ 1, -2,  4],
       [ 1, -1,  1],
       [ 1,  0,  0],
       [ 1,  1,  1],
       [ 1,  2,  4]])

相关内容

  • 没有找到相关文章

最新更新