这是我在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 4
和3 x 4
数组相乘。
最后,Octave中的bsxfun(@times, X*Y, X)
可能看起来像numpy.dot(X,Y) * X
。仍然有一些陷阱:例如,如果您期望外部乘积(即,在Octave中X是列向量,Y是行向量),您可以使用numpy.outer
来代替,或者注意X和Y的形状。
有点晚了,但我想提供一个在python中具有等效bsxfun
和repmat
的示例。这是我刚刚从Matlab转换到Python的一小段代码numpy:
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]])