[PYTHON] 수십 개의 배열을 가로 지르는 곱셈
PYTHON수십 개의 배열을 가로 지르는 곱셈
저는 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로 할 수있는 우아한 방법이 있는지 아는 사람 있습니까? 고마워. 알렉스
해결법
-
==============================
1.당신이 보여준 것과 같은 일반적인 곱셈은 :
당신이 보여준 것과 같은 일반적인 곱셈은 :
>>> 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]])
-
==============================
2.행렬 곱셈 (일명 곱법)을 사용할 수도 있습니다.
행렬 곱셈 (일명 곱법)을 사용할 수도 있습니다.
a = [[1,2,3],[4,5,6],[7,8,9]] b = [0,1,2] c = numpy.diag(b) numpy.dot(c,a)
어느 쪽이 더 우아한가는 아마도 맛의 문제 일 것입니다.
-
==============================
3.또 다른 트릭 (v1.6 현재)
또 다른 트릭 (v1.6 현재)
A=np.arange(1,10).reshape(3,3) b=np.arange(3) np.einsum('ij,i->ij',A,b)
나는 numpy 방송 (newaxis)에 능숙하지만, 나는이 새로운 einsum 도구에 대한 나의 길을 찾고있다. 그래서이 해결책을 찾기 위해 조금 놀았습니다.
타이밍 (Ipython timeit 사용) :
einsum: 4.9 micro transpose: 8.1 micro newaxis: 8.35 micro dot-diag: 10.5 micro
덧붙여서, i를 j로 변경하면, np.einsum ( 'ij, j-> ij', A, b)은 Alex가 원하지 않는 행렬을 생성합니다. 그리고 np.einsum ( 'ji, j-> ji', A, b)은 사실상 이중 전치 연산자입니다.
-
==============================
4.나는 스피드에 대한 다른 옵션들을 비교해 보았는데 놀랍게도 많은 것들이 (diag를 제외하고) 똑같이 빠르다는 것을 알았다. 나는 개인적으로 사용한다.
나는 스피드에 대한 다른 옵션들을 비교해 보았는데 놀랍게도 많은 것들이 (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)", )
-
==============================
5.너 왜 그래?
너 왜 그래?
>>> m = np.array([[1,2,3],[4,5,6],[7,8,9]]) >>> c = np.array([0,1,2]) >>> (m.T * c).T
??
from https://stackoverflow.com/questions/18522216/multiplying-across-in-a-numpy-array by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] OSx 업데이트 후 깨진 파이썬 2.7.11을 수정하는 방법 (0) | 2018.11.02 |
---|---|
[PYTHON] items () 대신 iteritems ()를 사용해야하는시기는 언제입니까? (0) | 2018.11.02 |
[PYTHON] 특수 문자에 대한 문자열을 확인하는 방법? (0) | 2018.11.02 |
[PYTHON] 문자열을 부분 문자열로 변환하는 방법이 있습니까? (0) | 2018.11.02 |
[PYTHON] 어떻게 장고에서 manytomany 필드를 업데이 트하려면? (0) | 2018.11.02 |