2013-06-30 3 views
2

나는 두뇌의 경과를 경험하고 있지만, 나는 이것을 작동시키지 못합니다. 거리의 배열을 가지고 있습니다 :numpy 배열에서 정사각형 거리를 계산하십시오.

import numpy as np 
zvals = np.linspace(-5,5,10) 
d = np.array([(0,0,z) for z in zvals]) 

배열의 점들의 제곱 거리를 계산하고 싶습니다. 이 일을 할 수있는 비 NumPy와 방법은 다음과 같습니다 그러나

d2 = np.array([np.dot(d[i,:],d[i,:]) for i in range(d.shape[0])]) 

, 난 지금, 점하는 단 하나의 호출로이 작업을 수행하는 몇 가지 방법이 있어야한다는을 알고 ? 그 어느 쪽도

d2 = np.dot(d,d.T) 

또는

d2 = np.dot(d.T,d) 

내가 원하는 것을주지 말했다되고. 나는 어리 석다, 나는 깨닫는다. 그러나 나에게 여기에서 밝혀주세요. 감사!

+0

Hmmm.np.diag (np.dot (d, d.T))가 작동하는 것처럼 보입니다. 더 좋은 방법이 있습니까 ?? – Rick

답변

6

편집 : NumPy 1.9부터 inner1d가 빠를 수 있습니다. (Nuno Aniceto에게 감사의 말을 전한다.) :

In [9]: %timeit -n 1000000 inner1d(d,d) 
1000000 loops, best of 3: 1.39 µs per loop 

In [14]: %timeit -n 1000000 einsum('ij,ij -> i', d, d) 
1000000 loops, best of 3: 1.8 µs per loop 

PS. 의도 한 유스 케이스와 유사한 입력에서 항상 벤치 마크를 테스트하십시오. 결과는 입력, 하드웨어, OS, Python 버전, NumPy 버전, 컴파일러 및 라이브러리 (예 : ATLAS, MKL, BLAS)의 크기와 같은 다양한 이유로 다양 할 수 있습니다.


NumPy 버전 1을 사용하는 경우.6 이상, 당신은 np.einsum 사용할 수 있습니다

In [40]: %timeit np.einsum('ij,ij -> i', d, d) 
1000000 loops, best of 3: 1.79 us per loop 

In [46]: from numpy.core.umath_tests import inner1d 

In [48]: %timeit inner1d(d, d) 
100000 loops, best of 3: 1.97 us per loop 

In [44]: %timeit np.sum(d*d, axis=1) 
100000 loops, best of 3: 5.39 us per loop 

In [41]: %timeit np.diag(np.dot(d,d.T)) 
100000 loops, best of 3: 7.2 us per loop 

In [42]: %timeit np.array([np.dot(d[i,:],d[i,:]) for i in range(d.shape[0])]) 
10000 loops, best of 3: 26.1 us per loop 
+0

와우. 나는 전에 einsum에 대해 들어 보지 못했다. 감사. – Rick

+0

'np.einsum'은 항상 +1을받습니다! 'inner1d'에 대한 타이밍을 추가 할 수 있습니까? 지금 당장은 시간을 낼 수 없지만 심각한 도전자라고 생각합니다. – Jaime

+0

@Jaime : 고마워, 하이메. 그것은 나를위한 새로운 것입니다. – unutbu

1

정상적인 내적 제품 방법을 더 큰 배열로 슬롯을 깔끔하게 만드는 방법이 있는지 확실하지 않습니다. 대신에, 나는 보통 수행이 배열에있는 모든 항목의 단지 elementwise 곱셈 이후

d2 = n.sum(d*d,axis=1) 

는 D의 *의 d는 물론 표준 내적 작업입니다. axis=1 인수는 내적 제품 작업의 두 번째 부분 인 두 번째 축을 따라 합계됩니다 (배열이 인쇄 될 때 가로 방향).

편집 : '을 위해 사용하는 경우 또한, 방법의 일반적인 바람직하지, 당신의 라인을 무시

d2 = np.array([np.dot(d[i,:],d[i,:]) for i in range(d.shape[0])]) 

d2 = np.array([np.dot(row,row) for row in d]) 

이 같은 NumPy와 배열은 개별 매트릭스 항목이 아닌 행을 반환 간단하게 할 수있다 배열로 '구문.

+0

니스! 나는 내가 이것을 할 np.dot을 원한다고 말했을 때 미루다. 난 단지 당신이 제공 한 것입니다 순수한 numpy 솔루션을 원한다. 감사! – Rick

+0

unutbu의 대답은 numpy 구문을 사용하는 것이 더 낫고 (더 빠릅니다!) 예를 들어 보았습니다. np.sum 메서드가 np.diag보다 약간 느리고 einsum보다 훨씬 느린 것 같습니다. – inclement

+0

감사합니다. – Rick

4

도트 제품 기능은 매우 빠르며, 아주 간단한 것들은 np.einsum을 이길 수도 있습니다 (이 기능은 확실히 사용법을 배워야합니다). Numpy는 감추어 진 작은 보석 인 inner1d을 가지고 있는데, 이는 논점의 마지막 차원에서 방송과 함께 내적 제품을 수행합니다. 다음과 같이 사용할 수 있습니다 :

from numpy.core.umath_tests import inner1d 
inner1d(a, a) 
관련 문제