본문 바로가기
학부 강의 노트/기상 인공지능 특론

넘파이(NumPy) 요약

by Dr. STEAM 2021. 11. 22.
반응형

파이썬 리스트는 활용도가 높지만, 빅데이터 처리에는 충분하지 않다. 

파이썬의 리스트에서는 데이터가 비연속적인 위치에 저당되므로 대량의 데이터 처라에 불리함. 

C언어 스타일의 2차원 배열은 데이터들이 연속적인 위치에 저장되어 효율적으로 처리할 수 있음. 왜냐하면 연속적으로 데이터가 저장되어 있어야 다음 데이터를 찾기 쉽기 때문. 

 

NumPy(Numerical Python):

과학/공학 분야에서 사용되는 파이썬 라이브러리

넘파이 API는 Pandas, SciPy, Matplotbli, scikit-learn 등의ㅐ 패키지에서 사용됨. 

훈련샘플은 2차원, 3차원 다차원 행렬안에 저장됨. 

행렬에서 삭제, 분리, 추가 등의 조작은 반드시 넘파이를 사용

 

넘파이 불러오기

>>> import numpy as np

배열 생성하기

배열은 넘파이의 핵심 데이터 구조

배열의 요소는 모두 동일한 타입

배열의 랭크(rank)는 차원 수

배열의 형상(shape)은 각 차원 및 항목 수

** 1차원 배열은 하나의 축만 가지고 있고, 2차원 배열은 2개의 축을 가진다.

배열생성은 array 함수 사용

a = np.array([1,2,3])  ## 1차원

#  a: 배열 객체

#  np.arry: 생성자 함수 

#  ([1,2,3]) : 파이썬 리스트

 

>>> a

array([1,2,3])

>>> a[0]

1

>>> b = np.array([[1,2,3],[4,5,6],[7,8,9]])

>>> b

arrary([[1,2,3],

         [4,5,6],

         [7,8,9]])

>>> b[0][2]

3

 

배열의 속성

넘파이 클래스 ndarray의 속성들

ndim : 축의 갯수, 2차원이면 ndim=2

shape: 배열의 형상, 정수 튜플로 나나냄. n행, m열의 경 (n,m)

size: 배열 내 요소들의 총 갯수

dtype: 배열 요소의 자료형,. numpy.int32, numpy.int16, numpy.float64 등

itemsize: 배열을 이루는 요소의 크기. 단위는 바이트. float64는 itemsize=8

data: 실제 데이터가 저장되는 메모리 블럭 주소

 

넘파이 배열 자료형 지정:

>>> dtype = np.int32  또는 dtype="np.int32"

 

>>> a=np.array([[0,1,2],

                      [3,4,5],

                      [6,7,8]])

>>> a.shape       # 배열의 형상

(3,3)

>>> a.ndim        # 배열의 차원 수

2

>>> a.dtype       # 요소의 자료형

dtype('int32')

>>> a.itemsize     # 요소 한개의 크기

8

>>> a.size   # 전체 요소 수 

9

 

1 또는 0으로 채워진 배열 생성 (주로 배열 초기화에 사용됨)

>>> np.zeros((3,4))
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
>>> np.ones((3,4))
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
>>> np.ones((3,4), dtype=np.int32)
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]])
>>> np.eye(3)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

 

>>> x = np.ones(5, dtype=np.int64)
>>> x
array([1, 1, 1, 1, 1], dtype=int64)

 

 

연속되는 값으로 배열 생성하기 

np.arange(start, stop, step)

>>> x = np.ones(5, dtype=np.int64)
>>> x
array([1, 1, 1, 1, 1], dtype=int64)
>>> np.arrange(5)
AttributeError: module 'numpy' has no attribute 'arrange'
>>> np.arange(5)
array([0, 1, 2, 3, 4])
>>> np.arange(1,6)
array([1, 2, 3, 4, 5])
>>> np.arange(1,6)
array([1, 2, 3, 4, 5])
>>> np.arange(1,10,2)
array([1, 3, 5, 7, 9])

 

 

np.linspace(start, stop, num)

start: 시작값

stop: 종료값

num: 갯수

>>> np.linspace(0,10,100)
array([ 0.        ,  0.1010101 ,  0.2020202 ,  0.3030303 ,  0.4040404 ,
        0.50505051,  0.60606061,  0.70707071,  0.80808081,  0.90909091,
        1.01010101,  1.11111111,  1.21212121,  1.31313131,  1.41414141,
        1.51515152,  1.61616162,  1.71717172,  1.81818182,  1.91919192,
        2.02020202,  2.12121212,  2.22222222,  2.32323232,  2.42424242,
        2.52525253,  2.62626263,  2.72727273,  2.82828283,  2.92929293,
        3.03030303,  3.13131313,  3.23232323,  3.33333333,  3.43434343,
        3.53535354,  3.63636364,  3.73737374,  3.83838384,  3.93939394,
        4.04040404,  4.14141414,  4.24242424,  4.34343434,  4.44444444,
        4.54545455,  4.64646465,  4.74747475,  4.84848485,  4.94949495,
        5.05050505,  5.15151515,  5.25252525,  5.35353535,  5.45454545,
        5.55555556,  5.65656566,  5.75757576,  5.85858586,  5.95959596,
        6.06060606,  6.16161616,  6.26262626,  6.36363636,  6.46464646,
        6.56565657,  6.66666667,  6.76767677,  6.86868687,  6.96969697,
        7.07070707,  7.17171717,  7.27272727,  7.37373737,  7.47474747,
        7.57575758,  7.67676768,  7.77777778,  7.87878788,  7.97979798,
        8.08080808,  8.18181818,  8.28282828,  8.38383838,  8.48484848,
        8.58585859,  8.68686869,  8.78787879,  8.88888889,  8.98989899,
        9.09090909,  9.19191919,  9.29292929,  9.39393939,  9.49494949,
        9.5959596 ,  9.6969697 ,  9.7979798 ,  9.8989899 , 10.        ])

 

배열 정렬

>>> arr = np.array([2,1,5,3,7,4,6,8])
>>> np.sort(arr)

배열 합치기

array([1, 2, 3, 4, 5, 6, 7, 8])
>>> x=np.array([[1,2],[3,4]])
>>> y=np.array([[5,6],[7,8]])
>>> np.concatenate((x,y), axis=1)
array([[1, 2, 5, 6],
       [3, 4, 7, 8]])

2개 배열 수직으로 쌓기

np.concatenate(), vstack(), hstack() 사용해도 됨.

>>> np.vstack((x,y))
array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])
>>> np.vstack(x,y)
TypeError: _vhstack_dispatcher() takes 1 positional argument but 2 were given
>>> np.hstack((x,y))
array([[1, 2, 5, 6],
       [3, 4, 7, 8]])

 

배열 형태 변환

일반적으로 딥러닝은 2차원 입력이어야 한다.

따라서, 1차원 자료를 2차원으로 변환해야 

reshape(): 행렬 데이터 갯수는 그대로, 차원만 변경함. 

new_array = old_array.reshape((2,3))

new_array: 새로운 배열

old_array: 원래 배열

(2,3): 새 배열 형상

 


>>> a = np.arange(12)
>>> a.shape
(12,)
>>> a.reshape(3,4)   # 3x4 행렬로 변환
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> a.reshape(6,-1)    #인수가 -1 인 경우, 데이터 갯수에 맞춰서 자동으로 배열형태 결정함. 
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11]])

 

다차원 배열 평탄화

다차원 배열 --> 1차원으로 

flatten() 사용 (ravel() 사용하면 view 만 변경되므로 주의.)


>>> y = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
>>> y.flatten()
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])


>>> a = y.flatten()
>>> a[0]= 99
>>> print(a)
[99  2  3  4  5  6  7  8  9 10 11 12]
>>> print(y)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

 

배열 분할(슬라이싱)

넘파이 배열을 자르는 메소드는 split()

세로로 자르려면 axis=1,가로면 axis=0

 

>>> array= np.arange(30).reshape(-1,10)
>>> array
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
>>> array= np.arange(30).reshape(-1,10)
>>> array
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
>>> arr1,arr2 = np.split(array, [3], axis=1)
>>> arr1
array([[ 0,  1,  2],
       [10, 11, 12],
       [20, 21, 22]])
>>> arr2
array([[ 3,  4,  5,  6,  7,  8,  9],
       [13, 14, 15, 16, 17, 18, 19],
       [23, 24, 25, 26, 27, 28, 29]])

 

 

배열에 새로운 축 추가하기

np.newaxis, np.expand_dims를 사용하여 기존 배열의 크기를 증가시킬 수 있음

np.newaxis를 사용할 때 마다 차원이 1차원 증가

 

>>> a = np.array([1,2,3,4,5,6])
>>> a.shape
(6,)
>>> a1=a[np.newaxis, :]
>>> a1.shape
(1, 6)
>>> a2=a[:, np.newaxis]

array([[1],
       [2],
       [3],
       [4],
       [5],
       [6]])
>>> a2.shape
(6, 1)

np.expand_dims() 를 사용하여 지정된 위치에 새 축을 삽입하여 배열 확장 가능

>>> b = np.expand_dims(a, axis=1)
>>> b
array([[1],
       [2],
       [3],
       [4],
       [5],
       [6]])
>>> b.shape
(6, 1)

 

인덱싱과 슬라이싱

>>> ages = np.array([18,19, 25, 30, 28])
>>> ages[1:3]    # index 1~2
array([19, 25])
>>> ages[:2]      # index 0~1
array([18, 19])
>>> y = ages > 20     # 논리 인덱싱
>>> y 
array([False, False,  True,  True,  True])

>>> ages[ages > 20]  ## 20 이상을 뽑아낼 때

array([25,30,28])

 

2차원 배열의 인덱싱

2차원 배열 인덱싱/슬라이싱은 가장 많이 사용됨. 연습 필요. 

>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a[0,2]
3
>>> a[0][2]
3
>>> 

>>> a[0,0] = 12
>>> a
array([[12,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9]])

 

 

2차원 배열 슬라이싱

>>> a[0:2, 1:3]
array([[2, 3],
       [5, 6]])

>>> a[0]

array([1,2,3])

>> a[1,1:3]

array([5,6])

 

얕은 복사와 깊은 복사

넘파이 함수, 인덱싱, 슬라이싱 연산자는 데이터 복사 필요없이 view 만 변환

view에서 데이터 수정하면 원본 배열도 수정됨. 

 

얕은 복사 예 ... b가 변하면 원본 a도 변한다.

>>> a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
>>> b = a[0,:]
>>> b
array([1, 2, 3, 4])
>>> b[0] = 99

>>> b
array([99, 2, 3, 4])
>>> a
array([[99,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

 

깊은 복사 예  ... b2는 변해도 원본 a는 변하지 않는다.

>>> b2 = a.copy()
>>> b2
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
>>> b2[0] = 88
>>> b2
array([[88, 88, 88, 88],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
>>> a
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

 

 

기본 배열 연산

>>> arr1 = np.array([[1,2],[3,4],[5,6]])
>>> arr2 = np.array([[1,1],[1,1],[1,1]])
>>> results = arr1 + arr2
>>> results
array([[2, 3],
       [4, 5],
       [6, 7]])
>>> arr1**2
array([[ 1,  4],
       [ 9, 16],
       [25, 36]], dtype=int32)

>>> arr1.sum()

21

>>> arr1.min()

1

>>> arr1.max()

6

>>> arr1.mean(axis=0)   # 특정 열에서의 모든 행의 값을 사용해서 계산

array([3., 4.,])

>>> arr1.mean(axis=1)   # 특정 열에서의 모든 열의 값을 사용해서 계산

array([1.5, 3.5, 5.5]

>>> print(arr1.T)   # 전치행렬

 

>>> arr1*arr2
array([[1, 2],
       [3, 4],
       [5, 6]])

 

>>> arr1 = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> arr2 = np.array([[2,2],[2,2],[2,2]])
>>> arr1 @ arr2     ## 내적 (1번째 열, 2번째 행 갯수 일치해야)
array([[12, 12],
       [30, 30],
       [48, 48]])

 

 

난수 생성

>>> np.random.seed(100) # 이후 아래 명령어 수행해야

>>>np.radom.rand(5)

>>> np.radom.rand(5,3)

>>> np.radom.randit(1,7,size=10)

 

>> > np.random.randn(5)  ## 정규분포 난수 생성

 a  = np.random.normal(loc=0.0, scale=1.0, size=None)

loc: 평균

scale: 표준편차

size: 배열의 차원

>> mu, sigma = 0, 0.1

>> np.random.normal(mu, sigma, 5)

array([-0.17497655,  0.03426804,  0.11530358, -0.0252436 ,  0.09813208])

 

 

 

고유 항목과 갯수 구하기 

>>> a = np.array([11,11,12,14,13, 15, 16, 17, 12, 13, 11, 14, 18, 19, 20])
>>> unique_values = np.unique(a)
>>> unique_values
array([11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
>>> uniuqe_values, indices_list = np.unique(a, return_index=True)

>>> print(indices_list)

[ 0 2 3 4 5 6 7 8 12 13 14]
>>> unique_values, occurrence_count = np.unique(a, return_counts=True)
>>> print(occurrence_count)
[3 2 2 2 1 1 1 1 1 1]

 

 

파일 입출력 (.csv)

Pandas 를 사용

read_csv()를 호출하면 반환되는 객체의 values에 넘파이배열로 저장됨. 

>>> import numpy as np

>>> import pandas as pd

>>> x= pd.read_csv('example.csv',  header=0).values  

>>> print(x)

 

>>> x= pd.read_csv('example.csv',  usecols=['col1','col2']).values  

>>> print(x)

 

>>> df = pd.DataFrame(a)

>>> print(df)

>> df.to_csv('out.csv')

 

 

 

728x90
반응형