ndarray 생성과 속성
1. NumPy 배열
1.1 ndarray 객체 생성
NumPy 배열은 ndarray(N-dimensional array) 객체로 표현되며, 다양한 방법으로 생성할 수 있습니다. 배열을 생성하는 가장 간단한 방법은 np.array() 함수를 사용하는 것입니다. 이 함수는 파이썬 리스트를 입력받아 NumPy 배열로 변환합니다. 이를 통해 파이썬 리스트보다 더 빠르고 효율적인 데이터 처리를 할 수 있습니다.
import numpy as np
# 1차원 배열(벡터)
arr1 = np.array([1, 2, 3, 4, 5])
print(arr1)
# 2차원 배열(메트릭스, 행렬)
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
# 3차원 배열(텐서)
arr3 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(arr3)
NumPy 배열은 다양한 차원을 가질 수 있으며, 1차원 배열은 벡터(Vector), 2차원 배열은 행렬(Matrix), 3차원 이상의 배열은 텐서(Tensor)로 부릅니다.
구글에서 개발한 텐서플로우(TensorFlow)와 같은 딥러닝 라이브러리의 이름에서 알 수 있듯이, 결국 인공지능도 행렬 연산으로 이루어진다는 것을 알 수 있습니다.
np.array() 말고도 다양한 방법으로 NumPy 배열을 생성할 수 있습니다. 예를 들어, np.zeros(), np.ones(), np.arange() 함수를 사용하여 0으로 채워진 배열, 1로 채워진 배열, 일정 간격의 숫자로 채워진 배열을 생성할 수 있습니다.
import numpy as np
# 0으로 채워진 배열 생성
zeros = np.zeros(5)
# 1로 채워진 배열 생성
ones = np.ones((2, 3))
# 일정 간격의 숫자로 채워진 배열 생성
range_arr = np.arange(1, 10, 2)
print("0으로 채워진 배열:", zeros)
print("1로 채워진 배열:", ones)
print("일정 간격의 숫자로 채워진 배열:", range_arr)
이에 대한 좀 더 상세한 내용은 다음 장에서 다루도록 하겠습니다.
1.2 데이터 타입
NumPy 배열은 다양한 데이터 타입을 지원하며, 배열 생성 시 자동으로 적절한 타입이 할당됩니다. 정수형, 실수형, 불리언, 복소수형 등 다양한 타입이 있으며, 각 타입은 서로 다른 특성과 사용 목적을 가집니다.
import numpy as np
정수 = np.array([1, 2, 3, 4, 5])
실수 = np.array([1.5, 2.7, 3.2])
불리언 = np.array([True, False, True])
print(정수.dtype)
print(실수.dtype)
print(불리언.dtype)
NumPy는 다양한 데이터 타입을 지원하며, 각 타입은 메모리 사용량과 표현 범위가 다릅니다. 다음은 NumPy에서 지원하는 주요 데이터 타입입니다.
| 데이터 타입 | 설명 | byte | 표현 범위 |
|---|---|---|---|
int8 | 8비트 정수 | 1 | -128 ~ 127 |
int16 | 16비트 정수 | 2 | -32,768 ~ 32,767 |
int32 | 32비트 정수 | 4 | 약 -21억 ~ 21억 |
int64 | 64비트 정수 | 8 | 매우 큰 범위 |
float32 | 32비트 실수 | 4 | 약 ±3.4E38 |
float64 | 64비트 실수 | 8 | 약 ±1.8E308 |
bool | 불리언 값 | 1 | True 또는 False |
complex64 | 복소수(32비트 실수부 + 32비트 허수부) | 8 | 복소수 표현 |
complex128 | 복소수(64비트 실수부 + 64비트 허수부) | 16 | 복소수 표현 |
타입은 배열 생성 시 자동으로 설정되며 dtype 매개변수를 통해 명시적으로 지정할 수 있습니다. 예를 들어, 아래와 같이 사용할 수 있습니다. 다만 주의해야 할 것은 bool같은 경우 내장 함수가 있어 bool_로 사용해야 합니다.
import numpy as np
정수 = np.array([1.5, 2.5, 3.5], dtype=np.int32)
실수 = np.array([1, 2, 3], dtype=np.float64)
print(정수, 실수)
2. 배열 속성
2.1 shape
shape 속성은 배열의 각 차원의 크기를 튜플로 반환합니다. 이는 배열이 몇 개의 행과 열로 구성되어 있는지, 또는 어떤 구조를 가지고 있는지 알 수 있게 해줍니다. 예를 들어, 2차원 배열의 shape이 (3, 4)라면, 이는 3행 4열의 구조를 가진 배열이라는 것을 의미합니다.

import numpy as np
# 1차원 배열
arr1 = np.array([1, 2, 3])
print(f"1차원 배열 shape: {arr1.shape}")
# 2차원 배열
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(f"2차원 배열 shape: {arr2.shape}")
# 3차원 배열
arr3 = np.array(
[[[1, 0, 3],
[0, 0, 6],
[0, 0, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]]
)
print(f"3차원 배열 shape: {arr3.shape}")
2.2 ndim
ndim 속성은 배열의 차원 수를 정수로 반환합니다. 이는 데이터 구조의 복잡도를 빠르게 파악하는 데 유용합니다. 1차원 배열은 ndim이 1, 2차원 배열은 2, 3차원 배열은 3을 반환합니다.
import numpy as np
# 1차원 배열
arr1 = np.array([1, 2, 3])
# 2차원 배열
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
# 3차원 배열
arr3 = np.array(
[[[1, 0, 3],
[0, 0, 6],
[0, 0, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]]
)
print(f"1차원 배열 ndim: {arr1.ndim}")
print(f"2차원 배열 ndim: {arr2.ndim}")
print(f"3차원 배열 ndim: {arr3.ndim}")
shape 과 ndim 무엇이 다를까?
| 특성 | ndim | shape |
|---|---|---|
| 의미 | 배열의 차원 수 | 각 차원의 크기 |
| 반환 타입 | 정수 | 튜플 |
| 예시 (1차원) | 1 | (4,) |
| 예시 (2차원) | 2 | (2, 2) |
| 예시 (3차원) | 3 | (2, 2, 2) |
| 제공 정보 | 배열이 몇 차원인지 | 각 차원의 구체적인 크기 |
| 사용 목적 | 배열의 차원 수 확인 | 배열의 구조 확인 |
이 표를 통해 ndim과 shape의 주요 차이점을 한눈에 비교할 수 있습니다. ndim은 차원의 수만을 간단히 알려주는 반면, shape은 각 차원의 구체적인 크기 정보를 제공합니다.
2.3 size
size 속성은 배열의 총 요소 수를 정수로 반환합니다. 이는 배열의 전체 크기를 한 눈에 파악하는 데 도움이 됩니다. 예를 들어, 3x4 크기의 2차원 배열의 size는 12입니다. 이 정보는 메모리 사용량을 예측하거나 배열 연산의 복잡도를 계산할 때 유용하게 사용됩니다.
import numpy as np
# 1차원 배열
arr1 = np.array([1, 2, 3])
# 2차원 배열
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
# 3차원 배열
arr3 = np.array(
[[[1, 0, 3],
[0, 0, 6],
[0, 0, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]]
)
print(f"1차원 배열 size: {arr1.size}")
print(f"2차원 배열 size: {arr2.size}")
print(f"3차원 배열 size: {arr3.size}")
2.4 dtype
dtype 속성은 배열의 데이터 타입을 반환합니다. 이는 배열 내 요소들의 타입을 알려주며, 메모리 사용량과 연산 정확도에 영향을 미칩니다. 예를 들어, int32는 32비트 정수를, float64는 64비트 부동소수점 수를 나타냅니다.
import numpy as np
arr4 = np.array([1, 2, 3], dtype=np.int32)
arr5 = np.array([1.0, 2.0, 3.0], dtype=np.float64)
arr6 = np.array([True, False, True])
print("정수 배열 dtype:", arr4.dtype)
print("실수 배열 dtype:", arr5.dtype)
print("불리언 배열 dtype:", arr6.dtype)