이번 포스팅에서는 넘파이 배열을 생성하는 방법과 넘파이 배열의 속성에 대해 알아보도록 하겠습니다.
import numpy as np
1. 넘파이 배열 생성하기
넘파이 배열을 만드는 여러 메서드가 존재합니다.
넘파이 라이브러리가 생성하는 모든 배열의 타입은 numpy.ndarray입니다.
✅ np.array
# a(스칼라)
a = np.array(3.14)
print(a)
# 3.14
b(벡터)
b = np.array([1, 2, 3])
print(b)
# [1 2 3]
c(행렬)
c = np.array([[1, 2, 3], [4, 5, 6]])
print(c)
# [[1 2 3]
# [4 5 6]]
d(3차원 텐서)
d = np.array([[[1, 2, 3],
[4, 5, 6]],
[[7, 8, 9],
[10, 11, 12]]])
print(d)
# [[[ 1 2 3]
# [ 4 5 6]]
# [[ 7 8 9]
# [10 11 12]]]
print(type(a)) # <class 'numpy.ndarray'>
print(type(b)) # <class 'numpy.ndarray'>
print(type(c)) # <class 'numpy.ndarray'>
print(type(d)) # <class 'numpy.ndarray'>
넘파이 배열을 생성하는 가장 기본적인 함수입니다.
✅ np.zeros, np.ones, np.full
- np.zeros(shape, ...)
- np.ones(shape, ...)
- np.full(shape, fill_value, ...)
m = np.zeros(shape=(2, 3))
print(m)
# [[0. 0. 0.]
# [0. 0. 0.]]
n = np.ones(shape=(4, 3))
print(n)
# [[1. 1. 1.]
# [1. 1. 1.]
# [1. 1. 1.]
# [1. 1. 1.]]
p = np.full(shape=(3, 3), fill_value=7)
print(p)
# [[7 7 7]
# [7 7 7]
# [7 7 7]]
np.zeros와 np.ones 메서드는 각각 0, 1로 구성된 넘파이 배열을 만듭니다.
np.full 메서드는 매개변수 fill_value를 사용해서 특정값으로 채워진 배열을 생성합니다.
세 함수 모두 매개변수 shape의 인수로 튜플을 전달해서 리턴 받을 배열의 형태를 지정할 수 있습니다.
✅ np.zeros_like, np.ones_like, np.full_like
- np.zeros_like(a, ...)
- np.ones_like(a, ...)
- np.full_like(a, fill_value, ...)
p = np.full(shape=(3, 3), fill_value=7)
print(p)
# [[7 7 7]
# [7 7 7]
# [7 7 7]]
zl = np.zeros_like(p)
print(zl)
# [[0 0 0]
# [0 0 0]
# [0 0 0]]
ol = np.ones_like(p)
print(ol)
# [[1 1 1]
# [1 1 1]
# [1 1 1]]
fl = np.full_like(p, fill_value=10)
print(fl)
# [[10 10 10]
# [10 10 10]
# [10 10 10]]
세 함수 모두 이미 선언된 배열로부터 새로운 넘파이 배열을 생성합니다.
np.zeros_like, np.ones_like 메서드는 인수로 전달한 배열과 동일한 형태의 배열을 각각 0, 1로 채웁니다.
np.full_like 메서드는 인수로 전달한 배열과 동일한 형태의 배열을 매개변수 fill_value의 인수로 채웁니다.
✅ np.arange
np.arange([start, ], stop, [step, ], ...)
a = np.arange(5)
print(a)
# [0 1 2 3 4]
b = np.arange(3, 8)
print(b)
# [3 4 5 6 7]
c = np.arange(2, 10, 2)
print(c)
# [2 4 6 8]
np.arange 메서드는 [start, stop) 범위에 존재하는 정수들로 구성된 배열을 리턴합니다.
매개변수 start에 인수를 전달하지 않으면 [0, stop) 범위에 존재하는 정수들로 구성된 배열을 리턴합니다.
파이썬 range 함수와 사용법이 같습니다.
print(np.arange(5.5))
# [0. 1. 2. 3. 4. 5.]
print(np.arange(1.5, 10.5))
# [1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5]
print(np.arange(1.5, 10.5, 2.5))
# [1.5 4. 6.5 9. ]
하지만 np.arange 메서드는 range 함수와 차이가 있습니다.
바로 실수 범위를 지정해서 실수값들로 구성된 배열을 생성한다는 점입니다.
✅ np.linspace
np.linspace(start, stop, num, ...)
print(np.linspace(0, 1, 5))
# [0. , 0.25, 0.5 , 0.75, 1. ]
[start, stop] 사이에 존재하는 균등한 간격의 수들로 이루어진 배열을 리턴합니다.
매개변수 num의 인수를 전달하면 리턴 받을 숫자들의 개수를 지정할 수 있습니다.
np.arange 메서드와는 차이가 있습니다.
np.linspace 메서드는 특정 구간의 수에 포커스를 두는 반면, np.arange 메서드는 구간에 초점을 둡니다.
arr = np.linspace([1, 10, 100], [2, 20, 200], 5)
print(arr)
# [[ 1. 10. 100. ]
# [ 1.25 12.5 125. ]
# [ 1.5 15. 150. ]
# [ 1.75 17.5 175. ]
# [ 2. 20. 200. ]]
매개변수 start, stop의 인수로 리스트를 전달하면 각 리스트의 원소를 조합해서 복수의 구간을 생성합니다.
아래 예제코드는 총 3개의 구간 [1, 2], [10, 20], [100, 200]을 지정합니다.
각 구간은 세로로 출력됩니다.
✅ np.random.randn, np.random.normal
- np.random.randn(d0, d1, ..., dn)
- np.random.normal(loc, scale, size)
# 평균이 -2, 표준편차가 1인 정규분포로부터 임의의 5개의 값을 샘플링
norm1 = np.random.normal(loc=-2, scale=1, size=(5,))
print(norm1)
# [-1.81109974 -2.14896005 -2.15722478 -3.17867298 -0.59277081]
print(type(norm1))
# <class 'numpy.ndarray'>
print(norm1.shape)
# (5,)
# 평균이 0, 표준편차가 2인 정규분포로부터 임의의 100개의 값을 샘플링
norm2 = np.random.normal(loc=0, scale=2, size=(100,))
# 평균이 3, 표준편차가 5인 정규분포로부터 임의의 200개의 값을 샘플링
norm3 = np.random.normal(loc=3, scale=5 ,size=(200,))
두 메서드는 각각 표준정규분포, 정규분포로부터 추출된 임의의 값들로 구성된 배열을 리턴합니다.
np.random.normal 메서드는 매개변수 loc으로 평균을, 매개변수 scale로 표준편차를 지정할 수 있습니다.
주로 테스트 데이터셋을 생성할 때 사용합니다.
students = np.random.normal(loc=[174.5, 78.5, 18],
scale=[13, 10, 1],
size=(100, 3))
print(students)
# array([[198.15216093, 66.86727979, 18.74544172],
# [179.84147129, 71.4853287 , 18.67180407],
# [182.29796423, 77.51904082, 16.54603387],
# ...
print(students.shape)
# (100, 3)
실제 테스트 데이터셋을 만들어보겠습니다.
아래 예제코드는 매개변수 loc, scale에 리스트를 전달해서 컬럼의 길이가 3인 2차원 배열을 생성합니다.
students를 출력하면 3개의 열이 나타나는데 각 열은 정규분포로부터 추출한 값들로 이루어집니다.
✅ np.random.rand, np.random.randint
- np.random.rand(d0, d1, ..., dn)
- np.random.randint(low, high, size, ...)
print(np.random.rand(2, 3))
# [[0.72791236 0.50691497 0.47625627]
# [0.54305228 0.15810855 0.18811806]]
np.random.rand 메서드는 [0, 1) 사이의 임의의 실수들로 이루어진 배열을 리턴합니다.
각 임의의 실수는 모두 균등분포로부터 샘플링됩니다.
print(np.random.randint(low=0, high=5, size=(5, )))
# [4 0 2 3 3]
np.random.randint 메서드는 [low, high) 사이의 임의의 정수들로 이루어진 배열을 리턴합니다.
✅ np.random.uniform
np.random.uniform(low, high, size)
print(np.random.uniform(0, 10, size=(5,)))
# [1.27630521 3.64290988 6.39384168 8.53930259 7.54249463]
균등분포의 [low, high] 구간에서 샘플링한 임의의 값들로 구성된 배열을 리턴합니다.
2. 넘파이 배열의 속성
넘파이 라이브러리 메서드로 생성한 배열은 모두 공통 속성을 가집니다.
각 속성을 적절하게 사용하면 다차원 배열의 연산 과정을 효율적으로 디버깅할 수 있습니다.
2-1. ndim
scalar = np.array(3.14)
print(scalar.ndim)
# 0
vector = np.array([1, 2, 3])
print(vector.ndim)
# 1
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(matrix.ndim)
# 2
tensor = np.array([[[1, 2, 3],
[4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
print(tensor.ndim)
# 3
배열의 차원을 리턴합니다.
대괄호가 몇번 열렸는지 확인하면 ndim 속성의 리턴값을 알 수 있습니다.
2-2. shape
scalar = np.array(3.14)
print(scalar.shape) # ()
print(len(scalar.shape)) # 0
vector = np.array([1, 2, 3])
print(vector.shape) # (3, )
print(len(vector.shape)) # 1
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(matrix.shape) # (2, 3)
print(len(matrix.shape)) # 2
tensor = np.array([[[1, 2, 3],
[4, 5, 6]],
[[7, 8, 9],
[10, 11, 12]]])
print(tensor.shape) # (2, 2, 3)
print(len(tensor.shape)) # 3
배열의 형태를 리턴합니다.
배열을 조작할 때 shape 속성에 대한 이해가 부족하면 디버깅을 할 때 어려움을 겪을 수 있습니다.
shape 속성이 리턴하는 값(튜플)의 길이는 ndim 속성이 리턴하는 값과 일치합니다.
a = np.array([1, 2, 3])
print(a) # [1 2 3]
print(a.shape) # (3, )
b = np.array([[1, 2, 3]])
print(b) # [[1 2 3]]
print(b.shape) # (1, 3)
c = np.array([[1], [2], [3]])
print(c)
# [[1]
# [2]
# [3]]
print(c.shape) # (3, 1)
브로드캐스팅의 원리를 정확히 알기 위해서는 다음 3가지 배열의 차이를 알아야 합니다.
각 배열의 shape에 주목해보세요.
이전에 shape에 대해 정리한 내용이 있는데 참고하면 shape의 중요성에 대해 알 수 있습니다.
넘파이 배열 shape 속성에 대한 이해
안녕하세요! 넘파이 라이브러리 관련 첫 포스팅입니다. 이번 첫 포스팅에서는 넘파이 배열의 shape 속성에 대해 알아보도록 하겠습니다. 넘파이 배열의 연산이 어떻게 수행되는지 알기 위해서는
parix-data.tistory.com
2-3. size
a = np.zeros(shape=(5, ))
print(a.size)
# 5
b = np.zeros(shape=(3, 5))
print(b.size)
# 15
c = np.zeros(shape=(2, 3, 4))
print(c.size)
# 24
d = np.zeros(shape=(2, 3, 4, 5, 6))
print(d.size)
# 720
배열 안 원소의 개수를 리턴합니다.
shape 속성이 리턴하는 튜플의 모든 원소를 곱하면 size 속성값과 일치합니다.
2-4. dtype
a = np.arange(100)
print(a.dtype)
# int64
b = np.full(fill_value=1.23, shape=(2, 3))
print(b.dtype)
# float64
배열 원소의 타입을 리턴합니다.
참고로 텐서플로우는 float32 데이터 타입을 사용한다고 합니다.
마치며
이상으로 넘파이 배열을 생성하는 메서드와 넘파이 배열의 기본 속성들에 대한 정리를 마치겠습니다.
다음 포스팅에서는 배열의 형태를 변환하는 reshape, resize 메서드에 대해 알아보도록 하겠습니다.
넘파이 배열의 형태 조작하기(reshape/resize)
이번 포스팅에서는 넘파이 배열의 형태를 조작하는 reshape, resize 메서드에 대해 알아보도록 하겠습니다. import numpy as np 1. reshape 메서드 - np.reshape(a, newshape, ...) - ndarray.reshape(shape, ...) reshape 메서드
parix-data.tistory.com
'파이썬・ML > numpy' 카테고리의 다른 글
넘파이 배열의 원소별 연산 이해하기(Element-wise operation) (0) | 2023.07.27 |
---|---|
넘파이 배열의 형태 조작하기(reshape/resize) (0) | 2023.07.27 |
넘파이 배열 shape 속성에 대한 이해 (0) | 2023.07.27 |
넘파이 np.repeat(), np.tile() 배열 반복하기 (0) | 2023.06.16 |
넘파이 np.hstack(), np.vstack(), np.concatenate() 배열 합치기 (0) | 2023.06.16 |