Python - NumPy 기초 (1)

4 분 소요

NumPy

데이터 처리에 사용되는 가장 대표적이고 기본적인 라이브러리.
과학/수학적 연산을 쉽고 빠르게 하기 위한 함수를 제공하여 다차원 배열 데이터를 효율적으로 처리할 수 있다.

NumPy 패키지 가져오기

import numpy as np

1. 배열 생성

  • np.array(seq_data) - 시퀀스 데이터로 numpy 배열 생성
  • np.arange(시작값, 끝값, 간격) - 범위를 지정해 numpy 배열 생성

배열의 속성 확인 (ndarray.속성)

  • ndarray.ndim: 차원수 확인
  • ndarray.shape: 배열의 모양을 튜플형태로 반환. (행, 렬)
  • ndarray.size: 배열의 크기
  • ndarray.dtype: 요소의 타입
  • ndarray.itemsize: 요소 데이터타입의 크기 (ex>int32 => 32bit, 4byte)
a = [1,2,3,4]  #파이썬 리스트
print(a)
print(type(a))
print(type(a[0]))
[1, 2, 3, 4]
<class 'list'>
<class 'int'>

 

arr = np.array(a)  #넘파이 배열 생성자 np.array()
print(arr)
print(type(arr))
print(arr.dtype)  #dtype: 요소 타입 확인
print(arr.shape)  #shape: 배열의 모양 확인, (행,열) 확인
[1 2 3 4]
<class 'numpy.ndarray'>
int32
(4,)

 

arr2 = np.array([5,6,7,8])  #1차원배열
print(arr2)
print(arr2.dtype)
print(arr2.shape)
[5 6 7 8]
int32
(4,)

 

arr3 = np.array([[1,2,3], [4,5,6]])  #2차원배열
print(arr3)
print(arr3.dtype)
print(arr3.shape)
print(arr3.ndim)  #dim: dimension 차원 수 확인
[[1 2 3]
 [4 5 6]]
int32
(2, 3)
2

 

arr4 = np.arange(10)  #연속된 숫자를 생성하여 배열 생성. 0에서 시작
print(arr4)
[0 1 2 3 4 5 6 7 8 9]

 

arr5 = np.arange(0, 10, 3)  #arrange(시작값, 끝값, 간격) - 0에서부터 10까지 간격을 3으로 갖는 배열 생성
print(arr5)
[0 3 6 9]

.reshape(m,n) - 배열의 형태를 m x n 형태의 2차원 배열로 변경

arr6 = np.arange(12)
print(arr6)
print(arr6.ndim)

arr6 = arr6.reshape(3,4)  #reshape(): 배열의 모양 변환
print(arr6)
print(arr6.ndim)  #모양에 따라 차원수도 바뀌었음을 확인가능
[ 0  1  2  3  4  5  6  7  8  9 10 11]
1
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
2

np.linspace(시작값, 끝값, 개수) - 시작값부터 끝값까지 지정한 개수만큼 균일한 간격으로 나눠진 numpy 배열 생성

  • 기본적으로 실수의 형태로 배열이 생성됨
  • 개수를 지정하지 않으면 50개로 간주함
arr7 = np.linspace(1, 10, 4)
print(arr7)
print(arr7.dtype)
[ 1.  4.  7. 10.]
float64

 

np.linspace(0, np.pi, 20)
array([0.        , 0.16534698, 0.33069396, 0.49604095, 0.66138793,
       0.82673491, 0.99208189, 1.15742887, 1.32277585, 1.48812284,
       1.65346982, 1.8188168 , 1.98416378, 2.14951076, 2.31485774,
       2.48020473, 2.64555171, 2.81089869, 2.97624567, 3.14159265])

연습

1. 1~10 사이의 홀수만 갖는 배열 생성

a = np.array([1,3,5,7,9])
a
array([1, 3, 5, 7, 9])

 

b = np.arange(1, 10 , 2)
b
array([1, 3, 5, 7, 9])

 

c = np.linspace(1, 9, 5)
c
array([1., 3., 5., 7., 9.])

2. 배열 d를 2줄 5칸으로 변형 하시오

d = np.arange(1, 11)
d = d.reshape(2, 5)
d
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])

3. d의 요소타입, 크기, 모양을 출력하시오

print(d.dtype)
print(d.size)
print(d[0].size)
print(d.shape)
int32
10
5
(2, 5)

특별한 형태의 배열 생성

.zeros()
np.zeros(n) - 모든 원소가 0으로 초기화된 1차원 배열 생성
np.zeros((m,n)) - 모든 원소가 0으로 초기화된 m x n 형태의 2차원 배열 생성

e = np.zeros((3,4))  #0으로 채워진 3줄 4칸 형태의 배열 생성 (기본 dtype = float64)
print(e.dtype)
e
float64

array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])

 

f = np.zeros((3,4), dtype=np.int32)  #dtype을 int로 변환
print(f.dtype)
int32

.ones()
np.ones(n) - 모든 원소가 1로 초기화된 1차원 배열 생성
np.ones((m,n)) - 모든 원소가 1로 초기화된 m x n 형태의 2차원 배열 생성

np.ones((3,4), dtype=np.int16)  #1로 채워진 3줄 4칸 형태의 정수 배열 생성
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]], dtype=int16)

.empty()
np.empty(n) - 특정한 값으로 초기화되지 않은 1차원 배열 생성
np.empty((n,m)) - 특정한 값으로 초기화되지 않은 m x n 형태의 2차원 배열 생성
np.empty_like(배열) - 입력한 배열의 크기와 동일하며 특정한 값으로 초기화되지 않은 배열 생성

‘초기화되지 않은’: 난수와 다른 임의의 값이 들어가며 값은 메모리에 저장된 내용에 따라 달라진다

np.empty([6,6]) #초기화되지 않은 값으로 배열 생성. 메모리도 초기화가 되어있지 않기때문에 예상치 못한 값들이 들어가있다
array([[ 0.00000000e+000,  0.00000000e+000,  0.00000000e+000,
         0.00000000e+000,  0.00000000e+000,  0.00000000e+000],
       [ 0.00000000e+000,  0.00000000e+000,  0.00000000e+000,
         0.00000000e+000,  0.00000000e+000,  0.00000000e+000],
       [ 0.00000000e+000, -1.35828224e-310,  1.86918699e-306,
         1.69121096e-306,  9.34604358e-307,  7.56587584e-307],
       [ 7.56593017e-307,  1.24610383e-306,  1.24610723e-306,
         1.37962320e-306,  1.29060871e-306,  2.22522597e-306],
       [ 1.33511969e-306,  1.78022342e-306,  1.05700345e-307,
         1.11261027e-306,  1.11261502e-306,  1.42410839e-306],
       [ 7.56597770e-307,  6.23059726e-307,  1.42419530e-306,
         7.56602523e-307,  1.29061821e-306,  1.37961234e-306]])

.full()
np.full(모양, 값) - 모든 값을 입력한 값으로 초기화한 배열을 모양대로 생성

np.full((2,3), 10, dtype=np.int32)  #full(모양, 값): 모든 값을 full 값으로 초기화
array([[10, 10, 10],
       [10, 10, 10]])

난수 배열의 생성
np.random.rand() - 실수 난수를 요소로 갖는 배열 생성
np.random.randint(최소값, 최대값, 모양) - 정수 난수를 요소로 갖는 배열 생성

np.random.rand(2,3)  #랜덤 값으로 배열 생성
array([[0.92462146, 0.59134101, 0.58196359],
       [0.5619506 , 0.86361081, 0.65527391]])

 

np.random.randint(10, size=(3,4))  #0~9 사이의 정수를 사용한 랜덤값으로 이루어진 3x4 배열 생성
array([[5, 8, 1, 7],
       [5, 3, 1, 2],
       [4, 5, 9, 1]])

단위행렬(identity matrix)
n x n인 정사각형 행렬에서 주 대각선이 모두 1이고 나머지는 0인 행렬

  • .identity(n)
  • .eye(n) 또는 .eye(n, m, k=x)
np.identity(4)  #n x n행으로 이루어진 단위행렬(identity matrix)을 생성
array([[1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]])

 

np.eye(4)  #identity(n)와 마찬가지로 단위행렬을 생성
array([[1., 0., 0., 0.],
       [0., 1., 0., 0.],
       [0., 0., 1., 0.],
       [0., 0., 0., 1.]])

 

np.eye(3,5)  #다른점은 n x m 으로도 생성이 가능하다는 점
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.]])

 

np.eye(3,5, k=2)  #k는 쉬프트 옵션. 오른쪽으로 쉬프트는 양수, 왼쪽으로 쉬프트는 음수
array([[0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

배열의 데이터 타입 변환

numpy 배열은 하나의 자료형만 가질 수 있다. 문자와 숫자가 섞여있을 경우 더 큰 데이터 타입인 문자로 통일된다.

요소 타입:
bool / int8, int16, int32, int64 / uint8, uint16, uint32, uint64 /
float16, float32, float64 / complex64, complex128 / string_

  • int, uint 모두 정수를 담는 타입
    • uint: unsigned int - 부호가 없다 = 양수를 표현
    • int8: 8비트 정수 (음수 128부터 양수 127까지, 총 256가지 숫자 표현)
    • uint8: 8비트 양수 (숫자 0부터 255까지 표현)
  • float(실수)는 부호가 필수여서 unsigned 형태가 없다

  • .astype(dtype) - 지정한 타입으로 요소의 데이터 타입 변환
    • 실수를 정수로, 문자를 실수로 바꿀 수도 있다
    • 실수를 정수로 바꾸는 경우 소수점은 모두 내린다
arr8 = np.array(['1.1','2.2','3.3','4.4'])
print(arr8.dtype) #dtype <U3 은 최대 3개의 철자를 가진 유니코드 문자열을 의미
<U3

 

arr8.astype(float)  #astype(): 타입변환
array([1.1, 2.2, 3.3, 4.4])

댓글남기기