TIL/Python

Python Library - Numpy와 ndarray

beady 2024. 11. 26. 10:32

- Numpy(Numerical Python) : 과학 계산에 강력한 성능을 제공하는 파이썬 라이브러리
다차원 배열 객체인 ndarray와 배열을 처리할 수 있는 다양한 함수를 제공
데이터 분석, 머신러닝, 딥러닝에서 기초가 되는 라이브러리이며, 판다스와 같이 자주 사용됨

 

먼저 리스트에서 요소를 연산하는 것과, 넘파이를 사용해 배열 전체에 연산하는 것이 어떻게 다른지 알아보자.

 

- 리스트 각 요소에 연산하기

sample_list = [1, 2, 3, 4, 5]

for i, v in enumerate(sample_list):
    sample_list[i] = v + 10
    
sample_list # [11, 12, 13, 14, 15]

 

 

- 넘파이를 사용해 배열을 생성하고 배열 전체에 연산하기

import numpy as np

arr = np.array([1, 2, 3, 4, 5])
arr += 10

arr # array([11, 12, 13, 14, 15, 16])

arr /= 2 # Error

※ 넘파이 배열은 벡터화 연산이 가능하여, 반복문 없이 배열 전체에 연산 가능

※ 복합 대입 연산자는 메모리 자체에 변경을 가하므로 데이터 타입이 일치하지 않는 경우 문제가 발생할 수 있음

※ 수학적인 연산 시 특히 주의 요망

 

 

- ndarray(n-dimensional array : n차원 배열)의 속성과 메서드

# 배열의 모양 변경
arr = np.array([1, 2, 3, 4, 5, 6])

arr_2 = arr.reshape((1, 6)) # 1개의 행과 6개의 열을 가지는 2차원 배열로 모양 변경
arr_2 # array([[1, 2, 3, 4, 5, 6]])

arr_3 = arr.reshape((2, 3)) # 2개의 행과 3개의 열을 가지는 2차원 배열로 모양 변경
arr_3 # array([[1, 2, 3],
      #        [4, 5, 6]])


# 행렬의 열과 행 개수 확인하기
arr.shape # (6,) 6개의 열을 가지는 1차원 배열
arr_2.shape # (1, 6) 1개의 행과 6개의 열을 가지는 2차원 배열
arr_3.shape # (2, 3) 2개의 행과 3개의 열을 가지는 2차원 배열

# 배열의 차원 확인하기
arr.ndim # 1
arr_2.ndim # 2
arr_3.ndim # 2

# 배열의 전체 요소 확인하기
arr.size # 6

# 배열의 데이터 타입 확인하기
arr.dtype # dtype('int32')

# 배열의 데이터 용량 확인하기
arr.nbytes # 24

# 잔차행렬 구하기
arr.T # array([1, 2, 3, 4, 5, 6])

# 1차원 배열로 변환하기
arr_3.ravel() # array([1, 2, 3, 4, 5, 6])
# ravel() 함수는 가능한 원본 배열을 반환함. 반환된 배열은 원본 배열과 메모리를 공유

arr_3.flatten() # array([1, 2, 3, 4, 5, 6])
# flatten() 함수는 항상 원본 배열의 복사본을 반환함. 원본 배열에는 영향을 미치지 않음

# 전치행렬
arr_3.transpose()
# array([[1, 4],
#        [2, 5],
#        [3, 6]])

# 모든 배열의 합
arr_3.sum() # 21

# 축을 기준으로 모든 행의 합
arr_3.sum(axis=0) # array([5, 7, 9])

# 축을 기준으로 모든 열의 합
arr_3.sum(axis=1) # array([ 6, 15])

# 배열의 평균과 최대값
arr_3.mean() # 3.5
arr_3.max() # 6
# 0 으로 구성된 배열 생성
np.zeros((2, 3))
# array([[0., 0., 0.],
#        [0., 0., 0.]])

# 1 로 구성된 배열 생성
np.ones((2, 3))
# array([[1., 1., 1.],
#        [1., 1., 1.]])

# 특정값으로 구성된 배열 생성
np.full((2, 3), 7)
# array([[7, 7, 7],
#        [7, 7, 7]])

arr_3 # array([[1, 2, 3],
      #        [4, 5, 6]])

# 특정 array와 동일한 형상의 특정값을 갖는 배열 생성
np.full((arr_3.shape), 8)
# array([[8, 8, 8],
#        [8, 8, 8]])

# 연속적인 값으로 채워진 배열 생성
np.arange(10) # 0부터 9까지의 연속된 값
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

# 다차원 배열의 인덱싱 및 슬라이싱
arr_4 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr_4 # array([[1, 2, 3],
      #        [4, 5, 6],
      #        [7, 8, 9]])
      
# 특정 원소 접근 / 인덱싱 (3행 2열)
arr_4[2, 1] # 8

# 슬라이싱 (2행 2열까지)
arr_4[:2, :2] # array([[1, 2],
              #        [4, 5]])

 

 

- 배열 연산 및 브로드캐스팅

브로드캐스팅 : 크기가 다른 배열 간에 일정 조건을 만족하면 연산을 가능하게 해주는 기능

조건 1) 원소가 하나인 배열은 어떤 배열이나 브로드캐스팅 가능

조건 2) 하나의 배열이 1차원 배열인 경우 브로드캐스팅 가능

조건 3) 차원의 짝이 맞을 때 브로드캐스팅 가능

arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr1 # array([[1, 2, 3],
     #        [4, 5, 6]])
arr2 = np.array([10, 11, 12])

arr1 + arr2 # array([[11, 13, 15],
            #        [14, 16, 18]])
            
np.add(arr1, arr2) # array([[11, 13, 15],
                   #        [14, 16, 18]])

 

 

- 서로 다른 크기의 배열 간 연산(작은 배열이 자동으로 확장되어 연산)

arr3 = np.array([1, 2, 3])
arr3 # array([1, 2, 3])

arr4 = np.array([[10], [20], [30]])
arr4 # array([[10],
     #        [20],
     #        [30]])
     
arr3 + arr4
# array([[11, 12, 13],
#        [21, 22, 23],
#        [31, 32, 33]])

 

 

- numpy add 메서드 주의사항 및 배열 간 요소 별 연산

arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([10, 12, 13, 14, 15])
arr3 = np.array([20, 21, 22, 23, 24])

np.add(arr1, arr2, arr3) # 세 배열의 합이 아닌 1, 2의 합을 3에 전달함
arr3 # array([11, 14, 16, 18, 20])

# 두 배열의 뺄셈
np.subtract(arr1, arr2)
# array([ -9, -10, -10, -10, -10])

# 두 배열의 곱셈
np.multiply(arr1, arr2)
# array([10, 24, 39, 56, 75])

# 두 배열의 요소별 나눗셈 후 소수점 이하 버림
np.floor_divide(arr2, arr1)
# array([10,  6,  4,  3,  3])

# 두 배열의 요소별 나눗셈 후 나머지 반환
np.mod(arr2, arr1)
# array([0, 0, 1, 2, 0])

# 각 요소별 제곱
arr2 ** arr1
# array([    10,    144,   2197,  38416, 759375])

 

 

- numpy의 집계 함수

# 배열의 요소 합
np.sum(arr1) # 15

# 배열의 요소 누적 곱
np.prod(arr1) # 120

# 배열의 요소 누적 합
np.cumsum(arr1) # array([ 1,  3,  6, 10, 15])

# 배열의 요소 평균
np.mean(arr1) # 3.0

# 배열의 요소 중간값
np.median(arr1) # 3.0

# 배열의 요소 표준편차
np.std(arr1) # 1.4142135623730951

# 배열의 요소 분산
np.var(arr1) # 2.0

# 배열의 최솟값인 요소의 위치
np.argmin(arr1) # 0

# 배열의 요소 최대, 최소의 범위 값
np.ptp(arr1) # 4

# 배열의 요소 자연 지수 함수
np.exp(arr1) # array([  2.71828183,   7.3890561 ,  20.08553692,  54.59815003,  148.4131591 ])