这是我在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的函数转换,但在我的情况下似乎没有帮助。
答案 0 :(得分:13)
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 3
和2 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中具有等效的bsxfun
和repmat
的示例。这是我刚刚从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]])