컴퓨터/Python

Python (6) - 넘파이(NumPy)로 알아보는 배열

달서비 2021. 8. 12. 23:07

파이썬에는 기본적으로 배열이 없습니다. (저도 처음에는 리스트를 배열하고 헷갈렸었습니다 ㅠㅠ) 리스트 같은 경우에는 동적이라 다루기 편합니다. 하지만 이미지(R, G, B)같이 같은 자료형들을 빠르게 사용한다면 결국 배열이 필요합니다. 그래서 이번에는 배열을 알아보겠습니다.

소스코드(주석)를 집중하여 봐주세요!

 

배열과 비슷한 형식을 가지고 있는 책꽂이

배열이란

  • 같은 특성을 가지며 일정한 자료형을 나열한 데이터의 집합이다 (변수는 다를 수도 있다)
  • 선형구조 중 기본적인 자료구조 (파이썬은 아니지만 C언어 등 다른 언어에서는 기본적으로 배운다)

파이썬에는 리스트라는 자료형이 있으나 그것은 배열과 다릅니다

그리고 위의 사진에 책꽂이가 배열과 비슷합니다 

 

사용방법

numpy는 설명하기에 방대한 양의 프로젝트라서 다 설명하기가 어렵습니다. 부족한 부분은 해당 웹사이트에 확인하면 됩니다. (본글은 아래 웹사이트의 NumPy Quickstart Tutorial 및 몇몇 사이트의 글을 재구성하여 적었습니다)

https://numpy.org/learn/

 

NumPy

For the official NumPy documentation visit numpy.org/doc/stable. NumPy Tutorials You can find a set of tutorials and educational materials by the NumPy community at NumPy Tutorials. The goal of this page is to provide high-quality resources by the NumPy pr

numpy.org

 

우선 기본으로 없기 때문에 numpy라는 모듈을 다운해서 사용해야 합니다

>> pip install numpy

 

1. 생성

#기본적인 numpy생성방법
import numpy

a = numpy.array([0, 2, 3, 4])
print(a) #[0,2,3,4]
print(a.dtype) #int32 (배열은 같은 자료형이 연속적으로있다)

b = numpy.array([[1,2,3],[1,2,2]])
print(b)
#[[1,2,3]
#[1,2,2]]

c = numpy.arange(10) # 0~9의 숫자가 입력되어 있는 배열을 만든다
print(c) #[0,1,2,3,4,5,6,7,8,9]

d = numpy.arange(10).reshape(2,5) #가로2 세로5 배열을 0~9꼴로 만든다
print(d) 
#[[0,1,2,3,4]
#[5,6,7,8,9]]

e = numpy.zeros(5) #0으로 초기화한 배열을 만든다
print(e) #[0,0,0,0,0]
print(e.dtype) #해당 자료형은 float다

f = numpy.ones((2,3,4)) #1로 초기화한 배열을 만든다
print(f) #3차원 배열도 가능은 하다
'''
[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]]
'''

g = numpy.linspace(0,9,10) #0~9까지 10등분한다
print(g)
# [0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]

다른 언어에서는 []를 통하여 배열을 생성하고 관리하지만 리스트가 이미 []를 통하여하고 있기 때문에 numpy.array([])꼴로 배열을 생성합니다. 그리고 numpy에 다양한 배열 생성 메서드들이 많아 나열해보았습니다.

 

2. 배열 연산

#numpy 연산
import numpy

#배열 선언
a = numpy.array([[1,2,3],[4,5,6]])
#[[1,2,3]
#[4,5,6]]
b = numpy.array([[2,2,2],[2,2,2]])
#[[2,2,2]
#[2,2,2]]

print(a+b) #더하기
#[[3,4,5]
#[6,7,8]]

print(a*b) #곱하기 행렬의 곱하기와 다르게 요소별로 곱한다
#[[2,4,6]
#[8,10,12]]


#브로드캐스팅 (밑에 별도 설명)
c = [5,5,5]
d = 10

print(a+c)
#[[6,7,8]
#[9,10,11]]

print(a+d)
#[[11,12,13]
#[14,15,16]]

numpy에서는 같은 배열끼리의 연산을 제공합니다. 같은 배열뿐만 아닌 다른 배열도 가능합니다. 이를 브로드캐스팅이라고 합니다. 반복되는 패턴으로 제공하기보다 더욱더 간단하게 자료형을 표시할 수 있습니다.

 

브로드캐스팅의 조건은 아래와 같습니다

0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

(예시로 표현한 4x4행렬)

  • 숫자 하나만 사용하는 경우 ex) 1
  • 열(가로축)의 크기가 일치하는 경우 ex) [1,2,3,4]
  • 행(세로축)의 크기가 일치하는 경우 ex) [[1], [2], [3], [4]]

사칙연산뿐만이 아닌 numpy에서는 행렬에 대한 계산도 할 수 있습니다.

#numpy 행렬 연산
import numpy

#배열 선언
a = numpy.arange(0,4).reshape(2,2)
#[[0,1]
#[2,3]]
b = numpy.array([[1,0],[0,1]]) #단위행렬
#[[1,0]
#[0,1]]

print(a*b) #각 행렬 원소의 곱
#[[0,0]
#[0,3]]
print(a@b) #행렬곱
#[[0,1]
#[2,3]]
print(a.dot(b)) #행렬내적
#[[0,1]
#[2,3]]

마지막으로 사칙연산, 행렬 계산뿐만이 아닌 모듈에 있는 메소드도 가지고 있습니다

#numpy 연산 메소드
import numpy

#배열 선언
a = numpy.arange(0,4).reshape(2,2)
#[[0,1]
#[2,3]]

print(a.sum()) #모든 원소들의 합
# 6
print(a.min()) #최소 원소의 값
# 0
print(a.max()) #최대원소의 값
# 3
print(a.argmax()) #배열 인덱스 크기
# 3
print(a.cumsum())  #누적합
# [0,1,3,6]

3. 배열 형태 변경

#numpy 연산 메소드
import numpy

#배열 선언
a = numpy.arange(0,12).reshape(3,4) #3x4의 배열을 만든다
#[[0,1,2,3]
# [4,5,6,7]
# [8,9,10,11]]

print(a.ravel()) #1차원 배열로 변경한다
#[0,1,2,3,4,5,6,7,8,9,10,11]

print(a.reshape(2,6)) #2x6으로 배열을 변경한다
#[[0,1,2,3,4,5]
# [6,7,8,9,10,11]]

print(a.T) #전치(행과열을 바꾸는것)
#[[0,4,8]
# [1,5,9]
# [2,6,10]
# [3,7,11]]

numpy에서는 배열의 모양을 바꿀 수 있습니다. 그 모양은 1차원이든 2차원이든 변환이 가능한 조건이면 변경할 수 있습니다 

 

마지막으로

numpy로 할 수 있는 것은 엄청나게 많다는 생각을 하지만, 가장 큰 예제로 생각하는 것은 opencv라는 모듈로 사진을 다룰 수 있습니다. 그뿐만이 아니라 위에서 적은 행렬을 구하는 방법이나 공학용 소프트웨어의 기능도 합니다. 배우면 배울수록 더욱더 기대가 되는 모듈입니다. 그리고 numpy를 더욱더 잘 쓰기 위하여 프로그래밍도 중요하지만 행렬을 잘아야 합니다