2017-10-13 12 views
1

를 사용하여 I 코드 가지고너무 많은 인덱스 np.where

a=b=np.arange(9).reshape(3,3) 
c=np.zeros(3) 

for x in range(3): 
    c[x]=np.average(b[np.where(a<x+3)]) 

c의 출력은 대신 루프의 >>>array([ 1. , 1.5, 2. ])

를, I는 (사용 어레이 싶어 벡터 라이 제이션), 다음 코드를 작성했습니다.

a=b=np.arange(9).reshape(3,3) 
c=np.zeros(3) 
i=np.arange(3) 
c[i]=np.average(b[np.where(a<i[:,None,None]+3)]) 

그러나 IndexEr ROR : a<i[:,None,None]+3

에 관해서는 배열

너무 많은 인덱스를 올바르게

array([[[ True, True, True], 
     [False, False, False], 
     [False, False, False]], 

     [[ True, True, True], 
     [ True, False, False], 
     [False, False, False]], 

     [[ True, True, True], 
     [ True, True, False], 
     [False, False, False]]], dtype=bool) 

을 보여줍니다하지만 b[np.where(a<i[:,None,None]+3)]를 사용할 때, 다시 IndexError 보여줍니다 배열에 대한 너무 많은 지수. c의 올바른 출력을 가져올 수 없습니다.

답변

1

명시 적으로 언급하지는 않았지만, 여기에있는 것들을 벡터화하려고한다는 것을 알고 있습니다. 자, 나는 당신이 그렇게 벡터화 된 방식으로 색인을 생성 할 수 있다고 생각하지 않습니다. 벡터화 된 방식으로 질문을 해결하려면 matrix-multiplication으로 np.tensordot을 사용하고 이미 시도한 것처럼 broadcasting의 도움을 받아 합계를 줄이는 더 효율적인 방법을 제안합니다.

따라서, 하나 개의 솔루션이 될 것이다 -

from __future__ import division 

i = np.arange(3) 
mask = a<i[:,None,None]+3 
c = np.tensordot(b,mask,axes=((0,1),(1,2)))/mask.sum((1,2)) 

Related post to understand tensordot. 성능

개선 가능한

  • 는 BLAS 계 매트릭스 곱셈으로 빨리되는 바와 np.dot에 공급하기 전에 DTYPE 부유 마스크 변환.

  • 부울 계산에 np.sum 대신 np.count_nonzero을 사용하십시오. 따라서 부품 번호 mask.sum()을 교체하십시오.

+0

합계 또는 평균은 단지 예제 일 뿐이므로 실제로는 'b [np.where (a

+0

@kinderchan 올바르게 이해하면 다음을 사용할 수 있습니다 : np.broadcast_to (b, mask.shape) [mask]? – Divakar

+0

시도해 보았지만 작동하지 않으며 b [mask, i [:, None]]도 사용합니다. –