Numpy-벡터 형식으로 함수 작성?

Sep 24 2020

나는 NumPy (또는 SciPy)를 처음 접했고 Octave / Matlab에서 왔는데, 이것은 나에게 약간 도전적인 것 같습니다.

나는 문서를 읽고 몇 가지 기본 기능을 작성하고 있습니다. 이 섹션을 보았습니다 : 함수 벡터화 (벡터화)

이 기능을 정의합니다.

def addsubtract(a, b):
   if a > b:
       return a - b
   else:
       return a + b

그런 다음 벡터화합니다.

vec_addsubtract = np.vectorize(addsubtract)

그러나 마지막에는 다음과 같이 말합니다.

이 특정 함수는 벡터화를 사용하지 않고 벡터 형식으로 작성 될 수 있습니다.

그런 함수를 작성하는 다른 방법은 모르겠습니다. 그렇다면 벡터 형태는 무엇입니까?

답변

1 MadPhysicist Sep 24 2020 at 18:57

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 튜토리얼의 향후 버전에서는 사용할 수 없습니다 .

NiklasMertsch Sep 24 2020 at 18:53

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 함수보다 훨씬 빠릅니다.