NumPy

LeeKyoungChang·2021년 11월 19일
0
post-thumbnail

1. NumPy

파이썬의 과학계산을 위한 가장 기본적인 라이브러리

행렬, 벡터 연산을 위한 사실상의 표준 라이브러로 빠른 처리속도가 장점

다차원 배열과 행렬 객체가 포함

ndarray를 핵심으로 선형대수 연산이 필요한 알고리즘에 사용

리스트보다 NumPy의 배열이 훨씬 빠르다.

  • NumPy의 핵심적인 객체는 다차원 배열이다.

  • ndarray는 C언어에 기반한 배열 구조이므로 메모리를 적게 차지하고 속도가 빠르다.

  • ndarray를 사용하면 배열과 배열 간에 수학적인 연산을 적용할 수 있다.

  • ndarray는 고급 연산자와 풍부한 함수들을 제공한다.

  • NumPy 배열에 +연산을 하면, 대응되는 값끼리 합쳐진 결과를 얻을 수 있다.

 

NumPy 패키지

import numpy as np

# 배열 생성
mid_scores = np.array([10,20,30])

 

NumPy의 핵심 다차원배열

a = np.array([1, 2, 3])
a.shape # a 객체의 형태 (배열의 차원)
a.ndim # 객체의 차원의 개수
a.dtype # a 객체 내부 자료형
a.itemsize # a 객체 내부 자료형이 차지하는 메모리 크기
a.size # a 객체의 전체 크기(항목의 수)

배열차원

import numpy as np

array_a = np.array([0,1,2,3,4,5,6,7,8,9])
print("실습 1 : array_a =",array_a)

array_b = np.array(range(10))
print('실습 2 : array_b =',array_b)

array_c = np.array(range(0,10,2))
print('실습 3 : array_c =',array_c)

print('실습 4: ')
print('array_c의 shape :',array_c.shape)
print('array_c의 ndim :',array_c.ndim)
print('array_c의 ctype :',array_c.dtype)
print('array_c의 size :',array_c.size)
print('array_c의 itemsize :',array_c.itemsize)

# 결과
# 실습 1 : array_a = [0 1 2 3 4 5 6 7 8 9]
# 실습 2 : array_b = [0 1 2 3 4 5 6 7 8 9]
# 실습 3 : array_c = [0 2 4 6 8]
# 실습 4:
# array_c의 shape = (5, )
# array_c의 ndim : 1
# array_c의 dtype : int32
# array_c의 size : 5
# array_c의 itemsize : 4

 

numpy.ndarray : attribute

배열2

ndarray 객체 배열 다루기

The array can be indexed using Python container-like syntax

  • 컨테이너(Container)란 자료형(Data type)의 저장 모델로 종류에 무관하게 데이터를 저장할 수 있음을 뜻한다.
  • 문자열, 튜플, 리스트, 사전, 집합 등은 종류에 무관(Container)한 형식이며, 정수, 실수, 복소수 등은 단일 종류한 형식이다.
  • 컨테이너 메서드(Container Method)는 위와같이 종류에 무관하게 저장할 수 있는 자료형의 매직 메서드(Magic:Method)를 뜻한다.
import numpy ad np

a = np.array([1, 2, 3]) # NumPy ndarray 객체의 생성
a  # array([1,2,3])
a.shape # a 객체의 형태 (3, )
a.ndim # a 객체의 차원 1
a.dtype # a 객체 내부 자료형 dtype('int32')
a.itemsize # a 객체 내부 자료형이 차지하는 메모리 크기(byte) 4
a.size # a 객체의 전체 크기(항목의 수) 3

Numpy

 

주의 사항

1) 넘파이의 배열 ndarray을 생성할 때, 반드시 대괄호를 사용하여 리스트 형식의 데이터를 만들어서 array() 함수의 인자로 넣어야 한다.

a = np.array([1,2,3,4])

그러지 않을 시 ValueError가 발생한다.

2) 넘파이의 ndarray는 리스트와는 달리, 서로 다른 자료형의 값을 원소로 가질 수 없다.

 

2. ndarray 객체 배열

ndarray의 메소드

a = np.array([1,2,3]) # 1차원 ndarray 배열 생성
a.max() # 가장 큰 값을 반환
a.min() # 가장 작은 값을 반환
a.mean() # 평균 값을 반환

append() 함수

a = np.array([1,2,3])
b = np.array([4,5,6],[7,8,9])
np.append(a,b) # array([1,2,3,4,5,6,7,8,9])
np.append([a],b,axis = 0) # [a]를 통해 2차원 배열로 만들어야 한다.
# array([[1,2,3],[4,5,6],[7,8,9]])

rand() 함수

np.random.rand(3,3) # (3,3) shape의 난수 생성
# array[[0.63208882,0.72259476,0.15125742],[0.60738882,0.20689476,0.51958342],[0.644331,0.91940484,0.83990604]]

flatten()

a = np.array([[1,1],[2,2],[3,3]])
a.flatten() # ndarray 배열의 평탄화 메소드
# array([1,1,2,2,3,3])

randint() 함수

np.random.randint(0, 10, size = 10) # 0에서 10까지의 10개의 난수 생성
# array([2, 0, 8, 2, 7, 0, 1, 3, 1, 3])

ndarray 연산

a = np.array([1,2,3]) # 1, 2, 3 원소를 가지는 1차원 ndarray
b= np.array([4,5,6]) # 4,5,6 원소를 가지는 1차원 ndarray
c = a + b
c
# array[5, 7, 9]

a = np.array([1,2])  # 2개의 원소를 가지는 1차원 배열 : (2,) shape
b = np.array([4,5,6]) # 3개의 원소를 가지는 1차원 배열 : (3,) shape
c = a + b # shape이 다른 1차원 배열의 합

# ValueError

a = np.array([[1,2],[3,4]]) # 2차원 배열 a
b = np.array([[10,20],[30,40]]) # 2차원 배열 b
a + b
# array([[11,22],[33,44]])
a - b
# array([[-9,-18],[-27,-36]])

np.matmul(a, b)
# array([[70, 100],[150, 220]])
# 행렬 곱셈 1 * 10 + 2 * 30 = 70

a * 100
# array([[100, 200],[300, 400]])

 

EX)

직원들의 월급이 [220, 250, 230]일 때

import numpy as np

salary = np.array([220,250,230])
salary = salary + 100 # 모든 값에 100을 더함
print(salary) # [320, 350, 330]

salary = np.array([220, 250, 230])
salary = salary * 2
print(salary) # [440, 500, 460]

 

넘파이의 배열 안에는 동일한 타입의 데이터만 저장할 수 있다.

임의 접근 : 원하는 위치에 바로 접근하여 데이터를 읽고 쓰는 일

임의 접근 기억장치(RAM) : 주기억 장치로 많이 쓰는 기억장치

 

ndarray 생성

NumPy는 배열을 쉽게 생성하는 함수도 지원하고 있다.

zeros(n, m) : n x m 배열(혹은 행렬)을 생성해서 초기값은 0

eye(n) : n x n 크기의 단위행렬 identity matrix을 생성 (정방행렬 중에서 대각선 성분이 1이고 나머지 성분이 0인 행렬)

np.zeros((2,3))
# array[[0.,0.,0.],[0.,0.,0.]] # 모든 값이 0인 2x3 크기 행렬
np.ones((2,3))
# arrray[[1.,1.,1.],[1.,1.,1.]] # 모든 값이 1인 2x3 크기 행렬

 

3. 배열 생성 및 데이터 생성 함수

arange() 함수

numpy.arange([start,] stop[, step,], dtype=None)

np.arange(0, 10)
# array([0,1,2,3,4,5,6,7,8,9])
np.arange(0,10,2)
# array([0,2,4,6,8])
np.arange(0,10,3)
# array([0,3,6,9])
np.arange(0.0, 1.0, 0.2)
# array([0. , 0.2, 0.4, 0.6, 0.8])

linspace() 함수
# 동일한 간격을 가진 연속된 값을 생성
# (시작, 끝, 간격의 수)를 인자로 가짐, 디폴트 간격의 수는 50개
np.linspace(0, 10, 5)
# array([0. , 2.5, 5., 7.5, 10. ])
np.linspace(0, 10, 4)
# array([0. , 3.3333, 6.66667, 10. ])

파이썬 리스트는 실수 step값을 사용할 수 없다.

 

arange() 함수와 range() 함수

np.arrange(1, 6)
# array([1,2,3,4,5])
np.arrange(1, 10, 2)
# array([1, 3, 5, 7, 9])

range(5)
# range(0, 5)
range(0, 5, 2)
# range(0, 5, 2)
list(range(5))
# [0, 1, 2, 3, 4]

np.array(range(5))
# array([0, 1, 2, 3, 4])

 

linspace() 함수와 logspace() 함수

linspace()는 상당히 많이 사용되는 함수이다.

linspace()는 시작값부터 끝값까지 균일한 간격으로 지정된 개수만큼의 배열을 생성

logspace()함수는 로그 스케일로 수들을 생성

numpy.linspace(start, stop, num=50)
# stop-1이 아니라 stop까지 생성
# 실수 데이터가 생성되고 start에서 stop까지 간격을 균일하게 쪼개어 num개의 실수를 생성
numpy.logspace(start, stop, num=50)
# 10^start 부터 10^stop까지의 실수를 로그 스케일로 볼 때 균등한 간격으로 num개수만큼 생성한다.

라이센스

 

배열의 형태를 바꾸는 reshpae() 함수와 flatten() 함수

reshape() 함수 : 데이터 개수는 유지한채로 배열의 차원과 형태를 변경

new_array = old_array.reshape(shape)
# shape에 변경하여 얻고 싶은 형태를 넘겨준다.

y.reshape(6, -1)
# 인수로 -1을 전달하면 데이터의 개수에 맞춰서 자동으로 배열의 형태가 결정
y.flatten()
# 2차원 이상의 고차원 배열을 1차원 배열로 만들어준다.

 

ndarray의 reshape

reshape() 메소드를 이용하여 1차원 배열을 2행5열의 다차원 행렬로 변환

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

 

4. Broadcasting(브로드캐스팅)

Shape이 같은 두배열에 대한 이항 연산은 배열의 요소별로 수행된다.

두 배열 간의 Shape이 다를 경우 두 배열 간의 형상을 맞추는 Broadcasting 과정을 거친다.

브로드캐스팅

Shape이 같은 두 배열을 이항 연산 할 경우 위치가 같은 요소 단위로 수행된다.

Shape이 다른 두 배열 사이의 이항 연산에서 브로드캐스팅 발생

두 배열을 같은 Shape으로 만든 후 연산을 수행

1) 배열과 스칼라

배열과 스칼라 사이의 이항 연산 시 스칼라를 배열로 변형한다.

2) Shape이 다른 배열들의 연산

큰 m * 큰 n 결과

 

5. 인덱싱과 슬라이싱

논리적인 인덱싱

ages = np.array([18, 19, 25, 30, 28])
ages[ages > 20]
# array([25, 30, 28])

인덱싱 슬라이싱

넘파일 배열은 모든 항목이 동일한 자료형을 가진다.

ex) 넘파이 배열의 형태 알아내고 슬라이싱하여 연산

import numpy as np

x = np.array([[1.83, 1.76, 1.69, 1.86, 1.77, 1.73],
             [86.0, 74.0, 59.0, 95.0, 80.0, 68.0]])

y = x[0:2, 1:3]  # 행 열
z = x[0:2][1:3]  # 공통 행 부분 1

print('x shape :', x.shape)
print('y shape :', y.shape)
print('z shape :', z.shape)
print('z values = :',z)

# 결과
# x shape : (2, 6)
# y shape : (2, 2)
# z shape : (1, 6)
# z values = : [[86. 74. 59. 95. 80. 68.]]

 

ex) 2차원 배열에서 특정 조건을 만족하는 행만 추출하기

import numpy as np

players = [[170, 76.4],[183, 86.2], [181, 75.5], [176, 80.1]]

np_players = np.array(players)

print('몸무게가 80 이상인 선수 정보')
print(np_players[ np_players[:, 1] >= 80.0 ])

print('키가 180 이상인 선수 정보')
print(np_players[ np_players[:, 0] >= 180.0 ])

# 결과
# 몸무게가 80 이상인 선수 정보
# [[183. 86.2][176. 80.1]]
# 키가 180 이상인 선수 정보
# [[183. 86.2][181. 78.5]]

 


참고 자료

  • 따라하며 배우는 파이썬과 데이터 과학, 생능출판사 강의자료
  • 학교 파이썬 수업, Numpy.pdf 강의자료
profile
"야, (오류 만났어?) 너두 (해결) 할 수 있어"

0개의 댓글

관련 채용 정보