import numpy as np
# 복합 조건도 사용 가능
complex_mask = (arr > 3) & (arr < 8)
result = arr[complex_mask]
print(result)
1.2 정수 배열을 이용한 팬시 인덱싱
팬시 인덱싱은 NumPy 배열에서 고급 데이터 접근 기법으로, 정수 배열이나 리스트를 인덱스로 사용하여 비연속적이거나 특정 패턴을 가진 요소들을 선택적으로 추출하는 방법입니다. 이 기법은 다차원 배열에서도 적용 가능하며, 원본 배열의 구조를 유지하면서 복잡한 데이터 선택 작업을 단일 연산으로 수행할 수 있게 해줍니다.
import numpy as np
arr = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
indices = [0, 2, -1] # 첫 번째, 세 번째, 마지막 요소 선택
selected = arr[indices]
print(selected)
np.newaxis를 사용하면 1차원 배열을 2차원 배열로 변환할 수 있습니다. 이를 통해 배열의 차원을 유연하게 조절하고, 다양한 연산을 수행할 수 있습니다. 이러한 기능은 데이터 전처리나 머신러닝 모델에서 데이터 형태를 맞추는 데 유용하게 사용됩니다. 데이터 복사 없이 뷰(view)를 생성하므로 메모리 효율적입니다.
import numpy as np
# 1차원 배열 생성
arr_1d = np.array([1, 2, 3, 4])
# 1차원 배열을 2차원 열 벡터로 변환
arr_2d_column = arr_1d[:, np.newaxis]
print("2D 열 벡터:")
print(arr_2d_column)
print("Shape:", arr_2d_column.shape)
import numpy as np
# 1차원 배열 생성
arr_1d = np.array([1, 2, 3, 4]) # 1차원 배열을 2차원 행 벡터로 변환
arr_2d_row = arr_1d[np.newaxis, :]
print("2D 행 벡터:", arr_2d_row)
print("Shape:", arr_2d_row.shape)
2.2 배열 전치(transpose)의 다양한 방법
배열 전치는 배열의 행과 열을 바꾸는 연산으로, T 속성이나 transpose 함수를 사용하여 수행할 수 있습니다. 이를 통해 데이터를 다양한 방식으로 재배열할 수 있으며, 다차원 배열에서는 축(axis)을 지정하여 원하는 대로 배열을 전치할 수 있습니다.
import numpy as np
# 3차원 배열 전치 (transpose 함수 사용)
arr_3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
arr_3d_transposed = np.transpose(arr_3d, (1, 0, 2))
print("\n전치된 3D 배열:")
print(arr_3d_transposed)
print("\n전치된 배열 shape:", arr_3d_transposed.shape)
3. 효율적인 연산 기법
3.1 브로드캐스팅
브로드캐스팅(Broadcasting)은 shape가 다른 배열 간의 산술 연산을 가능하게 합니다. 이 기능은 작은 배열을 자동으로 더 큰 배열의 shape에 맞게 확장하여 요소별 연산을 수행합니다. 이를 통해 복잡한 반복문 없이도 배열 간 연산을 간결하게 표현할 수 있습니다.
import numpy as np
# 5개 도시의 7일간 섭씨 온도 데이터
temp_c = np.array([
[20, 19, 21, 22, 23, 21, 20], # 도시 1
[18, 17, 19, 20, 21, 20, 19], # 도시 2
[25, 26, 27, 28, 27, 26, 25], # 도시 3
[15, 14, 16, 17, 18, 17, 16], # 도시 4
[22, 23, 24, 25, 24, 23, 22] # 도시 5
])
# 섭씨를 화씨로 변환 (브로드캐스팅 사용)
temp_f = (temp_c * 9/5) + 32
print("화씨 온도:")
print(temp_f)
# 각 도시의 평균 기온 계산 (axis=1은 행 방향, 즉 각 도시별로 평균 계산)
city_mean_f = np.mean(temp_f, axis=1, keepdims=True)
# 일별 기온과 도시 평균의 차이 계산 (브로드캐스팅 사용)
temp_diff = temp_f - city_mean_f
print("\n일별 기온과 도시 평균의 차이:")
print(temp_diff)
3.2 범용 함수
범용 함수(universal functions, ufunc)는 배열의 각 요소에 대해 연산을 수행하는 함수로, NumPy에서 제공하는 다양한 함수들이 이에 해당합니다. 이러한 함수는 벡터화 연산을 통해 반복문 없이 배열 요소에 대한 연산을 빠르게 처리할 수 있습니다.
범용 함수 함수는 단항 범용 함수 함수와 이항 범용 함수 함수로 구분됩니다. 단항 범용 함수 함수는 하나의 배열에 대해 연산을 수행하고, 이항 범용 함수 함수는 두 개의 배열 간 연산을 수행합니다.
단항 범용 함수 함수로는 np.abs, np.sqrt, np.exp, np.log, np.sin, np.cos, np.tan 등이 있으며, 이항 범용 함수 함수로는 np.add, np.subtract, np.multiply, np.divide, np.power, np.maximum, np.minimum 등이 있습니다.
import numpy as np
# 학생들의 점수 데이터 (5명의 학생, 3개 과목)
scores = np.array([
[80, 75, 85], # 학생 1
[90, 85, 95], # 학생 2
[70, 80, 75], # 학생 3
[85, 90, 80], # 학생 4
[95, 70, 90] # 학생 5
])
# 각 학생들의 총점 계산 (axis=1은 행 방향, 즉 각 학생별로 총점 계산)
np.sum(scores, axis=1)
# 각 학생의 총점 계산
np.add.reduce(scores, axis=1)
# 각 학생들의 평균 계산
np.mean(scores, axis=1)
# 각 학생들의 최고 점수 계산
np.max(scores, axis=1)
# 각 과목의 최고 점수 계산
np.maximum.reduce(scores, axis=0)
# 각 학생들의 성적을 100점 만점으로 환산
np.round(scores / 100 * 100)
# 각 학생들의 분산 계산
np.var(scores, axis=1)
# 각 학생들의 표준편차 계산
np.std(scores, axis=1)