Numpy-벡터 형식으로 함수 작성?
나는 NumPy (또는 SciPy)를 처음 접했고 Octave / Matlab에서 왔는데, 이것은 나에게 약간 도전적인 것 같습니다.
나는 문서를 읽고 몇 가지 기본 기능을 작성하고 있습니다. 이 섹션을 보았습니다 : 함수 벡터화 (벡터화)
이 기능을 정의합니다.
def addsubtract(a, b):
if a > b:
return a - b
else:
return a + b
그런 다음 벡터화합니다.
vec_addsubtract = np.vectorize(addsubtract)
그러나 마지막에는 다음과 같이 말합니다.
이 특정 함수는 벡터화를 사용하지 않고 벡터 형식으로 작성 될 수 있습니다.
그런 함수를 작성하는 다른 방법은 모르겠습니다. 그렇다면 벡터 형태는 무엇입니까?
답변
np.vectorizefornumpy가 제공하는 최적화를 효과적으로 제거한다는 것을 의미 하는 영광스러운 파이썬 루프입니다.
실제로 벡터화하기 위해 addsubtractnumpy가 벡터화 된 add함수, 벡터화 된 subtract함수 및 모든 종류의 부울 마스크 연산의 세 가지를 제공한다는 사실을 사용할 수 있습니다 .
이것을 작성하는 가장 간단하지만 효율성이 떨어지는 방법은 다음을 사용하는 것입니다 np.where.
np.where(a > b, a - b, a + b)
이 미리 계산해-때문에 비효율적 a - b와 a + b의 모든 경우에, 그리고 하나의 선택 또는 각각의 요소에 대한 다른.
더 효율적인 솔루션은 조건에 필요한 값만 계산합니다.
result = np.empty_like(a)
mask = a > b
np.subtract(a, b, where=mask, out=result)
np.add(a, b, where=~mask, out=result)
매우 작은 배열의 경우 복잡한 메서드의 오버 헤드로 인해 가치가 떨어집니다. 그러나 대형 어레이의 경우 가장 빠른 솔루션입니다.
재미있는 사실 : 참조하는 튜토리얼의 페이지는 PR # 12432에 설명 된대로 NumPy에 대한 소개이므로 SciPy 튜토리얼의 향후 버전에서는 사용할 수 없습니다 .
np.where두 결과 ( a-b및 a+b)를 모두 계산 하고 부울 배열 ( a>b) 에 따라 값을 선택하는을 사용 하여이 작업을 수행 할 수 있습니다 .
def addsubtract(a, b):
return np.where(a>b, a-b, a+b)
벡터화 된 삼항 연산자로 볼 수 있습니다. "여기서 a> b는 ab에서 값을 가져오고, 그렇지 않으면 a + b에서 값을 가져옵니다".
두 가지 가능한 결과를 모두 계산 했음에도 불구하고 (적어도 내 컴퓨터에서) 작성한 벡터화 된 if / else 함수보다 훨씬 빠릅니다.