用@times转换bsxfun为numpy

时间:2014-05-08 14:35:17

标签: python matlab numpy octave bsxfun

这是我在Octave中的代码:

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

代码的bsxfun部分产生逐元素乘法,所以我认为numpy.multiply(X*Y, X)可以做到这一点,但我得到了一个异常。当我进行一些研究时,我发现元素乘法不适用于Python数组(特别是如果X和Y的类型为“numpy.ndarray”)。所以我想知道是否有人可以解释这一点 - 即将类型转换为不同类型的对象工作? Octave代码有效,所以我知道我没有线性代数错误。我假设bsxfun和numpy.multiply实际上并不相同,但我不确定为什么所以任何解释都会很好。

我找到了website!这给了Octave到Matlab的函数转换,但在我的情况下似乎没有帮助。

3 个答案:

答案 0 :(得分:13)

Matlab中的

bsxfun代表二进制单例扩展,在numpy中称为广播,应该自动发生。解决方案将取决于X的维度,即是行或列向量,但此答案显示了一种方法:

How to multiply numpy 2D array with numpy 1D array?

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

答案 1 :(得分:3)

对于那些不了解Numpy的人,我认为值得指出的是Octave(和Matlab的)*运算符(矩阵乘法)相当于numpy.dot(并且,可辩论地,{{ 1}})。 Numpy的numpy.outer运算符与Octave中的*类似,它本身就是bsxfun(@times,...)的推广。

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

最后,Octave中的3 x 4可能看起来像bsxfun(@times, X*Y, X)。还有一些问题:例如,如果你期望一个外部产品(即,在Octave X中是一个列向量,Y是一个行向量),你可以看一下使用numpy.dot(X,Y) * X代替,或者要小心关于X和Y的形状。

答案 2 :(得分:0)

来晚了,但是我想提供一个在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]])