HOWTO · NumPy
NumPy에서 함수를 매핑하는 방법
numpy.vectorize() 또는 map()과 lambda를 사용해 Python 함수를 NumPy 배열의 모든 값에 적용합니다. 각 방법의 작동 방식과 사용 시점을 알아봅니다。
이 페이지의 내용
NumPy 배열의 각 값에 스칼라 Python 함수를 적용하려면 numpy.vectorize()로 함수를 감싸거나 Python의 map()과 lambda를 사용한 뒤 결과를 배열로 변환하면 됩니다. 두 방법 모두 스칼라 로직을 재사용할 때 유용합니다. 다만 NumPy에 같은 연산이 있다면 일반적으로 NumPy의 기본 배열 연산을 사용하는 편이 더 적합합니다.
numpy.vectorize()로 함수를 각 요소에 적용하기
numpy.vectorize()는 한 번에 값 하나를 받는 함수를 배열과 함께 호출할 수 있도록 해 줍니다. 감싼 함수를 배열의 각 요소에 차례로 적용하고 결과 배열을 반환합니다. 기존 Python 로직이 스칼라 값을 처리하도록 작성되어 있고 이를 배열 데이터에 적용하고 싶을 때 편리합니다.
다음 예제에서는 입력값의 제곱을 구하는 스칼라 함수를 감싼 다음, 정수 다섯 개에 적용합니다.
import numpy as np
def square(value):
return value ** 2
values = np.array([1, 2, 3, 4, 5])
square_each = np.vectorize(square)
result = square_each(values)
print(result)
여기서 square는 일반 Python 함수로 그대로 유지되고, np.vectorize()가 배열을 대상으로 호출할 수 있는 인터페이스를 제공합니다. 이는 편의를 위한 래퍼이지 성능 최적화가 아닙니다. 함수를 컴파일된 NumPy 연산으로 바꾸지는 않습니다. NumPy가 이미 지원하는 산술 연산이라면 values ** 2와 같은 식이 더 간단하며 NumPy의 배열 연산을 직접 사용합니다. 스칼라 로직을 적용하는 편이 코드의 명확성이나 재사용성을 높일 때 numpy.vectorize()를 사용하세요.
lambda 함수와 함께 map() 사용하기
Python 내장 함수인 map()은 반복 가능한 객체의 각 항목에 함수를 한 번씩 호출합니다. lambda는 짧은 함수를 코드 안에서 간결하게 정의하는 방법입니다. 입력이 NumPy 배열이면 map()은 변환된 값의 반복자를 만듭니다. 이 반복자를 list()로 감싼 다음, 결과 목록을 np.array()에 전달하면 배열을 만들 수 있습니다.
다음 예제에서는 lambda로 같은 값들의 제곱을 구한 다음, 변환된 값을 NumPy 배열로 만듭니다.
import numpy as np
values = np.array([1, 2, 3, 4, 5])
mapped_values = map(lambda value: value ** 2, values)
result = np.array(list(mapped_values))
print(result)
lambda는 배열의 각 값을 하나씩 받고, map()은 각 값의 제곱을 순서대로 내놓습니다. 반복자를 목록으로 변환하면 반복자가 소진됩니다. 그런 다음 np.array()가 목록의 값으로 배열을 만듭니다. 이 방법은 매핑 호출 바로 옆에 둘 수 있는 짧은 스칼라 연산에 편리합니다. 로직이 길다면 읽고 유지 관리하기 쉽도록 이름 있는 함수를 정의하고, lambda 대신 그 함수를 map()에 전달하세요.
기존 스칼라 함수에 배열 형태의 호출 인터페이스를 제공하려면 numpy.vectorize()를 선택하세요. 짧은 변환을 인라인으로 표현하려면 map()과 lambda를 사용하세요. 특히 변환 전의 반복자를 활용할 수 있을 때 유용합니다. 모든 값의 제곱처럼 NumPy가 직접 지원하는 연산에는 의도한 계산을 잘 나타내는 경우 values ** 2와 같은 NumPy 식을 우선 사용하세요. 이 방법들은 Python 로직을 적용하는 서로 다른 방식이며, 어느 한쪽이 더 빠르다는 근거가 되지는 않습니다.