NumPy에서 2차원 배열/행렬의 각 요소에 함수/맵 값을 적용하는 방법
NumPy에서 2차원 배열/행렬의 각 요소에 함수/맵 값을 적용하는 방법
다음은 NumPy에서 이 작업을 수행하는 몇 가지 방법입니다.
np.apply_along_axis 사용:
np.apply_along_axis
함수는 특정 축에 따라 함수를 배열에 적용합니다. 다음은 2차원 배열의 각 행에 제곱 함수를 적용하는 예시입니다.
import numpy as np
# 2차원 배열 생성
arr = np.array([[1, 2, 3], [4, 5, 6]])
# 각 행에 제곱 함수 적용
squared_rows = np.apply_along_axis(lambda x: x**2, 0, arr)
print(squared_rows)
# [[ 1 4 9]
# [16 25 36]]
벡터화된 연산 사용:
NumPy는 많은 연산을 벡터화하여 루프 없이 배열 전체에 효율적으로 적용할 수 있습니다. 다음은 2차원 배열의 각 요소에 제곱근을 계산하는 예시입니다.
# 각 요소에 제곱근 계산
sqrt_elements = np.sqrt(arr)
print(sqrt_elements)
# [[ 1. 1.41421356 1.73205081]
# [ 2. 2.23606798 2.44948974]]
np.vectorize 사용:
np.vectorize
함수는 일반 Python 함수를 NumPy ufunc로 변환하여 배열에 효율적으로 적용할 수 있도록 합니다. 다음은 2차원 배열의 각 요소에 로그 함수를 적용하는 예시입니다.
# 로그 함수 벡터화
log_func = np.vectorize(np.log)
# 각 요소에 로그 함수 적용
log_elements = log_func(arr)
print(log_elements)
# [[ 0. 0.69314718 1.09861229]
# [ 1.38629436 1.60943791 1.79175947]]
for 루프 사용:
간단한 경우 for 루프를 사용하여 2차원 배열의 각 요소에 함수를 직접 적용할 수 있습니다.
# 각 요소에 제곱 함수 적용
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
arr[i, j] = arr[i, j]**2
print(arr)
# [[ 1 4 9]
# [16 25 36]]
map 함수 사용:
map
함수를 사용하여 2차원 배열의 각 요소에 함수를 적용하고 결과를 새로운 배열에 저장할 수 있습니다.
# 각 요소에 제곱 함수 적용
squared_elements = list(map(lambda x: x**2, arr.flatten()))
# 결과 배열 생성
squared_arr = np.array(squared_elements).reshape(arr.shape)
print(squared_arr)
# [[ 1 4 9]
# [16 25 36]]
위의 방법 중 상황에 맞는 가장 적합한 방법을 선택하십시오. 벡터화된 연산을 사용하는 것이 일반적으로 가장 효율적이지만, 람다 함수를 사용해야 하는 경우 np.apply_along_axis
또는 map
함수를 사용하는 것이 더 간편할 수 있습니다.
참고:
np.vectorize
:
예제 코드
import numpy as np
# 2차원 배열 생성
arr = np.array([[1, 2, 3], [4, 5, 6]])
# **1. `np.apply_along_axis` 사용**
# 각 행에 제곱 함수 적용
squared_rows = np.apply_along_axis(lambda x: x**2, 0, arr)
print("**`np.apply_along_axis` 사용**")
print(squared_rows)
# **2. 벡터화된 연산 사용**
# 각 요소에 제곱근 계산
sqrt_elements = np.sqrt(arr)
print("**벡터화된 연산 사용**")
print(sqrt_elements)
# **3. `np.vectorize` 사용**
# 로그 함수 벡터화
log_func = np.vectorize(np.log)
# 각 요소에 로그 함수 적용
log_elements = log_func(arr)
print("**`np.vectorize` 사용**")
print(log_elements)
# **4. for 루프 사용**
# 각 요소에 제곱 함수 적용
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
arr[i, j] = arr[i, j]**2
print("**for 루프 사용**")
print(arr)
# **5. `map` 함수 사용**
# 각 요소에 제곱 함수 적용
squared_elements = list(map(lambda x: x**2, arr.flatten()))
# 결과 배열 생성
squared_arr = np.array(squared_elements).reshape(arr.shape)
print("**`map` 함수 사용**")
print(squared_arr)
결과:
**`np.apply_along_axis` 사용**
[[ 1 4 9]
[16 25 36]]
**벡터화된 연산 사용**
[[ 1. 1.41421356 1.73205081]
[ 2. 2.23606798 2.44948974]]
**`np.vectorize` 사용**
[[ 0. 0.69314718 1.09861229]
[ 1.38629436 1.60943791 1.79175947]]
**for 루프 사용**
[[ 1 4 9]
[16 25 36]]
**`map` 함수 사용**
[[ 1 4 9]
[16 25 36]]
2차원 배열/행렬의 각 요소에 함수/맵 값을 적용하는 대체 방법
# 각 요소에 제곱 함수 적용
squared_elements = [x**2 for x in arr.flatten()]
# 결과 배열 생성
squared_arr = np.array(squared_elements).reshape(arr.shape)
print(squared_arr)
NumPy ufunc 사용:
# 제곱 ufunc 사용
squared_arr = np.square(arr)
print(squared_arr)
브로드캐스팅:
# 각 행에 10을 더하기
arr += 10
print(arr)
np.einsum 사용:
# 행렬 곱셈
result = np.einsum("ij,ij->ij", arr, arr)
print(result)
Cython 사용:
# Cython 코드
cdef int[:, :] squared_arr
def square_array(int[:, :] arr):
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
squared_arr[i, j] = arr[i, j]**2
# Cython 함수 호출
squared_arr = square_array(arr)
print(squared_arr)
위의 방법 중 상황에 맞는 가장 적합한 방법을 선택하십시오.
팁:
- 작은 배열에 대해서는 for 루프나 리스트 컴프리헨션을 사용하는 것이 가장 간단할 수 있습니다.
- 큰 배열에 대해서는 벡터화된 연산,
np.einsum
또는 Cython을 사용하는 것이 더 효율적일 수 있습니다. - 코드를 작성하기 전에 NumPy 문서를 참고하여 사용 가능한 다양한 함수와 기능을 확인하십시오.
numpy