2011-03-08 3 views
2

numpy에서 행렬을 곱하는 문제가 있습니다.numpy tensordot 관련 문제

P[0]*P[0][:,np.newaxis] 
array([[0, 0, 0], 
    [0, 1, 2], 
    [0, 2, 4]]) 

저장 :

P=np.arange(30).reshape((-1,3)) 
array([[ 0, 1, 2], 
    [ 3, 4, 5], 
    [ 6, 7, 8], 
    [ 9, 10, 11], 
    [12, 13, 14], 
    [15, 16, 17], 
    [18, 19, 20], 
    [21, 22, 23], 
    [24, 25, 26], 
    [27, 28, 29]]) 

제가 첫번째 행에 대한 예를 들면, 행마다 를 3 × 3 행렬을 획득하기 위해 그 전치 각 행을 곱 할 : 여기 은 일례이며 3-D 매트릭스 M에 결과 :

M=np.zeros((10,3,3)) 
for i in range(10): 
    M[i] = P[i]*P[i][:,np.newaxis] 

나는 어쩌면 텐서 점으로, 반복하지 않고 할 수있는 방법이있을 수 있습니다 생각하지만, 그것을 찾을 수 없습니다.

누군가 아이디어가 있습니까?

답변

3

그것은이 같은 단지 간단합니다 : 이것은 부분적으로 tensordot()을 사용하여 문제를 해결

In []: P= arange(30).reshape(-1, 3) 
In []: P[:, :, None]* P[:, None, :] 
Out[]: 
array([[[ 0, 0, 0], 
     [ 0, 1, 2], 
     [ 0, 2, 4]], 
     [[ 9, 12, 15], 
     [ 12, 16, 20], 
     [ 15, 20, 25]], 
     [[ 36, 42, 48], 
     [ 42, 49, 56], 
     [ 48, 56, 64]], 
     #... 
     [[729, 756, 783], 
     [756, 784, 812], 
     [783, 812, 841]]])  
In []: P[1]* P[1][:, None] 
Out[]: 
array([[ 9, 12, 15], 
     [12, 16, 20], 
     [15, 20, 25]]) 
+1

위대한, 정확히 내가 뭘 찾고 있었는지, 거기에 쉬운 방법론은 없음으로 확장해야 색인을 이해하는 것입니다? –

+0

@ 안드레아 Z : 그런 방법론; 먼저 'numpy'방송이 실제로 어떻게 작동하는지 알아 내려고합니다. 그런 다음 당신이 '모양 = (10, 3, 3)'을 찾고 있음을 깨달으면'(P [:, :, None] * P [:, None, :]). 모양 == (10, 3, 3)'. 아마도 가장 좋은 설명은 아니지만, 내가 강조하는 요점은; 어떻게 방송이 작동하는지 자신을 숙지하십시오. 이제 '방송의 내장'에 대한 다른 질문을 자유롭게하십시오! 감사합니다 – eat

1

나는 stride_tricks를 좋아하기 때문에 그게 내가 사용하는 것입니다. 나는 다른 방법이있을 것이라고 확신합니다.

배열의 보폭과 모양을 3D로 확장되도록 변경하십시오. P의 "전치 된"버전으로 쉽게 똑같은 일을 할 수 있습니다. 그러나 여기에서 나는 그것을 재구성하고 방송 규칙에 따라 다른 차원으로 스트레칭하게합니다. 이 stride_tricks.as_strided의 좋은 자세한 설명이 있기 때문에

P=np.arange(30).reshape((-1,3)) 
astd = numpy.lib.stride_tricks.as_strided 
its = P.itemsize 
M = astd(P,(10,3,3),(its*3,its,0))*P.reshape((10,1,3)) 

나는 this post에 대한 참조를 추가거야.

+0

+1 stride_tricks는 정말 훌륭하지만 파악하기가 복잡합니다. –

0

,

from numpy import arange,tensordot 

P = arange(30).reshape((-1,3)) 

i = 3 

T = tensordot(P,P,0)[:,:,i,:] 

print T[i] 
print tensordot(P[i],P[i],0) 

T

당신이 원하는 (더) 모든 제품을 포함, 그것은 추출 단지 질문 그들.

+0

OP는'tensordot (.) '을 사용할 가능성이 있다고 추측했지만, 실제로 코드에서는 아무것도 필요하지 않습니다. 당신의 솔루션은 실행 시간과 메모리 소비가 현저히 비싸다. 자신의 솔루션과 다른 솔루션을 비교할 수있는 벤치 마크를 만들었습니까? 감사합니다. – eat

+0

@eat : 참으로 비싼 메모리입니다. 이 예제에서는 10 x 3 배열로,'tensordot()'를 사용하면 실행 시간이 대략 두 배가됩니다. 배열 크기가 커짐에 따라 점점 더 나 빠지게됩니다. – lafras

+1

나는 명백하게 설명하지는 않았지만, 완전히 다른 이유로 tensordot이 그것을 할 수있는 방법이 아닙니다. 'P'를 랭크 -2 텐서로 보는다면'P'의 결과에 대해 3 가지 옵션 만 존재합니다. 1) 모든 인덱스가 rank-0 텐서 (스칼라)를 남기지 않습니다. 2) 1 인덱스 집합이 취소되고 랭크 -2 텐서 (행렬)가 남아 있거나 3) 둘 다 취소되지 않고 랭크 4 텐서가 남습니다. OP는 rank-3 텐서를 답으로 원했고,'tensordot()'는 랭킹 4 제품을 슬라이스하지 않는 한 당신에게주지 않았습니다. – lafras