numpy 배열에서 곱하기
2D 배열의 각 항에 1D 배열의 해당 항을 곱하려고합니다. numpy.multiply 함수에 표시된 것처럼 모든 열에 1D 배열을 곱하려는 경우 매우 쉽습니다 . 그러나 저는 반대로 행의 각 항을 곱하고 싶습니다. 즉, 곱하고 싶습니다.
[1,2,3] [0]
[4,5,6] * [1]
[7,8,9] [2]
그리고 얻다
[0,0,0]
[4,5,6]
[14,16,18]
그러나 대신 나는
[0,2,6]
[0,5,12]
[0,8,18]
numpy로 우아한 방법이 있는지 아는 사람이 있습니까? 고마워, Alex
당신이 보여준 것과 같은 정상적인 곱셈 :
>>> 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]])
축을 추가하면 원하는 방식으로 곱해집니다.
>>> m * c[:, np.newaxis]
array([[ 0, 0, 0],
[ 4, 5, 6],
[14, 16, 18]])
두 번 전치 할 수도 있습니다.
>>> (m.T * c).T
array([[ 0, 0, 0],
[ 4, 5, 6],
[14, 16, 18]])
속도에 대한 다른 옵션을 비교 한 결과 놀랍게도 모든 옵션 (제외 diag
)이 똑같이 빠릅니다. 나는 개인적으로
A * b[:, None]
(또는 (A.T * b).T
) 짧기 때문입니다.
플롯을 재현하는 코드 :
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)",
)
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.
Yet another trick (as of 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.
Timings (using 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.
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)).
>>> 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]])
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
??
참고 URL : https://stackoverflow.com/questions/18522216/multiplying-across-in-a-numpy-array
'Programing' 카테고리의 다른 글
행렬의 각 행에 numpy.linalg.norm을 적용하는 방법은 무엇입니까? (0) | 2020.11.27 |
---|---|
URL에서 원격 이미지의 너비 높이 가져 오기 (0) | 2020.11.27 |
Java에서 교착 상태 감지 (0) | 2020.11.27 |
Python Decimals 형식 (0) | 2020.11.27 |
jQuery 지연이 작동하지 않음 (0) | 2020.11.27 |