728x90
반응형
NumPy 벡터화와 루프 제거로 성능 극대화하기
NumPy는 파이썬에서 고성능 수치 계산을 가능하게 해주는 필수적인 라이브러리입니다. 특히 대규모 데이터를 다룰 때, NumPy의 벡터화(Vectorization) 기능을 활용하면 반복문(loop)을 제거하여 실행 속도를 대폭 향상시킬 수 있습니다. 오늘은 NumPy 벡터화의 개념과 이를 활용하여 반복문을 제거하는 방법을 실제 예제와 함께 알아보겠습니다.
벡터화(Vectorization)란 무엇인가?
벡터화는 반복문을 사용하지 않고 배열 연산을 통해 데이터를 처리하는 방법입니다. NumPy는 내부적으로 C로 작성된 고성능 코드로 작동하므로, 벡터화를 활용하면 Python 반복문보다 훨씬 빠르게 연산을 수행할 수 있습니다.
벡터화의 주요 이점
- 성능 향상: 파이썬의 반복문은 느리지만, NumPy는 배열 단위로 연산을 처리하여 성능을 극대화합니다.
- 코드 간결성: 복잡한 반복문을 단일 배열 연산으로 대체하여 코드가 간단하고 읽기 쉬워집니다.
반복문과 벡터화의 성능 비교
먼저 반복문을 사용하여 두 배열의 요소를 더하는 예제를 작성해보고, 이후 벡터화를 적용한 코드를 비교해 보겠습니다.
예제: 반복문을 이용한 배열 합
import numpy as np
import time
# 큰 배열 생성
size = 10**6
array1 = np.random.rand(size)
array2 = np.random.rand(size)
# 반복문으로 배열 합
start_time = time.time()
result = np.zeros(size)
for i in range(size):
result[i] = array1[i] + array2[i]
end_time = time.time()
print(f"반복문으로 계산한 시간: {end_time - start_time:.5f}초")
예제: 벡터화를 이용한 배열 합
# 벡터화로 배열 합
start_time = time.time()
result = array1 + array2
end_time = time.time()
print(f"벡터화로 계산한 시간: {end_time - start_time:.5f}초")
위 코드를 실행하면 벡터화가 반복문보다 훨씬 빠르게 실행되는 것을 확인할 수 있습니다.
다양한 벡터화 예제
1. 조건에 따른 배열 요소 변경
반복문 방식
# 배열 생성
array = np.array([1, 2, 3, 4, 5])
# 반복문으로 조건 처리
result = np.zeros_like(array)
for i in range(len(array)):
if array[i] % 2 == 0:
result[i] = array[i] * 2
else:
result[i] = array[i] * 3
print(result)
벡터화 방식
# 벡터화로 조건 처리
result = np.where(array % 2 == 0, array * 2, array * 3)
print(result)
2. 유클리드 거리 계산
반복문 방식
# 두 점의 좌표
points = np.random.rand(1000, 2)
distances = np.zeros((1000, 1000))
# 반복문으로 거리 계산
for i in range(1000):
for j in range(1000):
distances[i, j] = np.sqrt(np.sum((points[i] - points[j])**2))
print(distances)
벡터화 방식
# 벡터화로 거리 계산
differences = points[:, np.newaxis, :] - points[np.newaxis, :, :]
distances = np.sqrt(np.sum(differences**2, axis=-1))
print(distances)
3. 배열의 누적합 계산
반복문 방식
# 배열 생성
array = np.array([1, 2, 3, 4, 5])
result = np.zeros_like(array)
# 반복문으로 누적합 계산
current_sum = 0
for i in range(len(array)):
current_sum += array[i]
result[i] = current_sum
print(result)
벡터화 방식
# 벡터화로 누적합 계산
result = np.cumsum(array)
print(result)
벡터화와 메모리 사용량 주의점
벡터화를 사용할 때는 배열 크기가 매우 클 경우 메모리 사용량이 증가할 수 있습니다. 따라서 메모리 사용량을 관리하기 위해 필요한 경우 메모리 매핑(memory mapping)이나 청크 단위로 연산을 고려해야 합니다.
벡터화를 활용한 실전 사례
이미지 처리
이미지 데이터를 처리할 때 벡터화를 활용하면 픽셀 단위의 반복 작업을 빠르게 수행할 수 있습니다.
예제: 이미지 밝기 조절
import cv2
# 이미지 불러오기
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 밝기 조정 (반복문 방식)
adjusted_image = np.zeros_like(image)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
adjusted_image[i, j] = min(image[i, j] + 50, 255)
# 밝기 조정 (벡터화 방식)
adjusted_image = np.clip(image + 50, 0, 255)
cv2.imwrite('adjusted_image.jpg', adjusted_image)
마무리
NumPy의 벡터화를 사용하면 복잡한 반복문을 단순하고 빠르게 대체할 수 있습니다. 벡터화는 데이터 분석, 머신러닝, 신호 처리 등 다양한 분야에서 활용도가 높으니, 여러분도 적극적으로 활용해 보세요.
반응형
'Python > NumPy' 카테고리의 다른 글
| NumPy와 Pandas 연동하기: 효율적인 데이터 처리를 위한 기초 가이드 (0) | 2025.10.24 |
|---|---|
| NumPy와 Python 리스트 성능 비교 (0) | 2025.10.23 |
| NumPy를 사용한 성능 최적화 기법 (0) | 2025.10.21 |
| NumPy 텍스트 파일 읽기 및 쓰기 (loadtxt, savetxt) (0) | 2025.10.20 |
| NumPy 배열 파일 저장 및 로드 (save, load, savez) (0) | 2025.10.19 |