Python 在 numpy 数组中相乘
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18522216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiplying across in a numpy array
提问by Alex S
I'm trying to multiply each of the terms in a 2D array by the corresponding terms in a 1D array. This is very easy if I want to multiply every column by the 1D array, as shown in the numpy.multiplyfunction. But I want to do the opposite, multiply each term in the row. In other words I want to multiply:
我试图将二维数组中的每个项乘以一维数组中的相应项。如果我想将每一列乘以一维数组,这很容易,如numpy.multiply函数所示。但我想做相反的事情,将行中的每个项相乘。换句话说,我想乘以:
[1,2,3] [0]
[4,5,6] * [1]
[7,8,9] [2]
and get
并得到
[0,0,0]
[4,5,6]
[14,16,18]
but instead I get
但我得到了
[0,2,6]
[0,5,12]
[0,8,18]
Does anyone know if there's an elegant way to do that with numpy? Thanks a lot, Alex
有谁知道 numpy 是否有一种优雅的方式来做到这一点?非常感谢,亚历克斯
采纳答案by jterrace
Normal multiplication like you showed:
正常乘法就像你展示的那样:
>>> import numpy as np
>>> m = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> c = np.array([0,1,2])
>>> m * c
array([[ 0, 2, 6],
[ 0, 5, 12],
[ 0, 8, 18]])
If you add an axis, it will multiply the way you want:
如果您添加一个轴,它将以您想要的方式相乘:
>>> m * c[:, np.newaxis]
array([[ 0, 0, 0],
[ 4, 5, 6],
[14, 16, 18]])
You could also transpose twice:
您也可以转置两次:
>>> (m.T * c).T
array([[ 0, 0, 0],
[ 4, 5, 6],
[14, 16, 18]])
回答by James K
You could also use matrix multiplication (aka dot product):
您还可以使用矩阵乘法(又名点积):
a = [[1,2,3],[4,5,6],[7,8,9]]
b = [0,1,2]
c = numpy.diag(b)
numpy.dot(c,a)
Which is more elegant is probably a matter of taste.
哪个更优雅可能是品味问题。
回答by hpaulj
Yet another trick (as of v1.6)
另一个技巧(从 v1.6 开始)
A=np.arange(1,10).reshape(3,3)
b=np.arange(3)
np.einsum('ij,i->ij',A,b)
I'm proficient with the numpy broadcasting (newaxis
), but I'm still finding my way around this new einsum
tool. So I had play around a bit to find this solution.
我精通 numpy 广播 ( newaxis
),但我仍在寻找解决这个新einsum
工具的方法。所以我玩了一会儿来找到这个解决方案。
Timings (using Ipython timeit):
计时(使用 Ipython timeit):
einsum: 4.9 micro
transpose: 8.1 micro
newaxis: 8.35 micro
dot-diag: 10.5 micro
Incidentally, changing a i
to j
, np.einsum('ij,j->ij',A,b)
, produces the matrix that Alex does not want. And np.einsum('ji,j->ji',A,b)
does, in effect, the double transpose.
顺便说一下,将 a 更改i
为j
,np.einsum('ij,j->ij',A,b)
会产生 Alex 不想要的矩阵。并且np.einsum('ji,j->ji',A,b)
实际上是双重转置。
回答by Panos
Why don't you just do
你为什么不做
>>> m = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> c = np.array([0,1,2])
>>> (m.T * c).T
??
??
回答by Nico Schl?mer
I've compared the different options for speed and found that – much to my surprise – all options (except diag
) are equally fast. I personally use
我比较了不同的速度选项,发现——出乎我的意料——所有选项(除了diag
)都同样快。我个人使用
A * b[:, None]
(or (A.T * b).T
) because it's short.
(或(A.T * b).T
)因为它很短。
Code to reproduce the plot:
重现情节的代码:
import numpy
import perfplot
def newaxis(data):
A, b = data
return A * b[:, numpy.newaxis]
def none(data):
A, b = data
return A * b[:, None]
def double_transpose(data):
A, b = data
return (A.T * b).T
def double_transpose_contiguous(data):
A, b = data
return numpy.ascontiguousarray((A.T * b).T)
def diag_dot(data):
A, b = data
return numpy.dot(numpy.diag(b), A)
def einsum(data):
A, b = data
return numpy.einsum("ij,i->ij", A, b)
perfplot.save(
"p.png",
setup=lambda n: (numpy.random.rand(n, n), numpy.random.rand(n)),
kernels=[
newaxis,
none,
double_transpose,
double_transpose_contiguous,
diag_dot,
einsum,
],
n_range=[2 ** k for k in range(14)],
logx=True,
logy=True,
xlabel="len(A), len(b)",
)
回答by Christopher Pratt
For those lost souls on google, using numpy.expand_dims
then numpy.repeat
will work, and will also work in higher dimensional cases (i.e. multiplying a shape (10, 12, 3) by a (10, 12)).
对于那些在 google 上迷失的灵魂,使用numpy.expand_dims
thennumpy.repeat
可以工作,并且也可以在更高维度的情况下工作(即将形状 (10, 12, 3) 乘以 (10, 12))。
>>> import numpy
>>> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
>>> b = numpy.array([0,1,2])
>>> b0 = numpy.expand_dims(b, axis = 0)
>>> b0 = numpy.repeat(b0, a.shape[0], axis = 0)
>>> b1 = numpy.expand_dims(b, axis = 1)
>>> b1 = numpy.repeat(b1, a.shape[1], axis = 1)
>>> a*b0
array([[ 0, 2, 6],
[ 0, 5, 12],
[ 0, 8, 18]])
>>> a*b1
array([[ 0, 0, 0],
[ 4, 5, 6],
[14, 16, 18]])