728x90
개요
- 수학, 과학, 공학, 데이터과학 응용 분야에서 python에서 사용 가능한 open source library
- C/C++ Fortran과 통합이 쉬움
- 데이터 구조
- ndarray class: array class라고 부르기도 함
- 동일한 데이터형 원소들(주로 숫자형)의 다차원 배열
- indexing: 정수들의 tuple로 index 표현
- broadcasting
- 다양한 수치 연산 도구
- 다차원 배열에 적용할 수 있는 벡터화 함수
- 선형 대수, 푸리에 변환, 콘볼루션, 통계 라이브러리 등
Numpy 장점
- 다차원 배열 또는 행렬 연산의 편리함
- 우수한 메모리 효율(list, tuple에 비해) // list객체가 약 130배 정도 늦음
- 빠른 처리속도
<aside> 💡 np.array() # 다차원 배열 생성
</aside>
Numpy 다차원 배열과 list 객체의 구조 비교
- List
- 이질(heterogeneous) 데이터형 원소 가능(다른 유형의 객체 가능)
- 동적 배열
- Numpy 다차원 배열
- 동질(homogeneous) 데이터형 원소만 가능
- 고정 크기 배열: 배열 추가/제거 불가능. 추가제거 위해서는 객체 새로 만들어야 함
Numpy 다차원 배열을 이용한 1차원 벡터의 표현과 연산
import numpy as np
a = np.array([1, 3, 5, 3, 1])
b = np.array([3, 5, 7, 1, 2])
a + b # array([4, 8, 12, 4 ,3])
# 벡터 행렬, 산술 연산 매우 간단!
2 * a # array([2, 6, 10, 6, 2])
# 스칼라 * 벡터 연산 가능
Numpy 다차원 배열 class ndarray의 주 attributes
- ndarray.ndims: axes-축(dimensions)의 수
- ndarray.shape: axes별 원소의 개수를 tuple로 표현
- ndarray.size: 원소의 개수
- ndarray.dtype: numpy.int32, numpy.int16, numpy.floar64 등
- ndarray.itemsize: 각 원소의 크기를 byte단위로 표현
- ndarray.nbytes: 전체 데이터의 크기를 byte단위로 표현
na = np.random.randint(1, 10, (3, 4))
# 1 ~ 10 정수 중 난수로 3*4 배열 return
# attributes
na.ndim # 2: 2차원배열이므로
na.shape # (3, 4): 3*4 행렬이므로
na.dtype # dtype('int32'): 32bit 정수형
na.size # 12: 원소가 12개
na.itemsize # 4: 32bits = 4bytes
na.nbytes # 48: 12개 * 4bytes = 48bytes
Numpy ndarray 객체의 데이터형
Numpy 정수형의 overflow와 underflow
- 정수를 원소로 갖는 numpy의 ndarray object는 표현 가능한 bit수가 사전에 정해짐 > overflow, underflow 발생 가능.
import numpy as np
a = np.array([100, 200], np.int8)
a # array([100, -56], dtype=int8)
# signed int8의 최댓값은 128, overflow 발생
np.iinfo(np.int8)
# iinof(min=-128, max=127, dtype=int8)
# 8bit signed integer max/min value
a + a # array([-56, -112], dtype=int8)
3 * a # array([44, 88], dtype=int8)
# underflow 발생
b = np.array([100, 200], np.uint8)
b # array([100, 200], dtype=uint8)
2 * b # array([100, 1440, dtype=uint8)
# overflow 발생
Ndarray 생성
list, tuple 이용 ndarray 생성
data1 = (1, 2, 3, 4, 5) # tuple의 모든 원소 데이터 유형이 같아야 함
# arr 생성법> numpy의 array class의 instance 만들기.
# list, tuple과 같은 객체를 전달(sequence type only?)
arr1 = np.array(data1) # 1d array
arr1 # array([1, 2, 3, 4, 5])
arr1.dtpye # dtype('int32')
# 별도의 data type 지정않는 경우 32가 default
arr1.ndim # 1: 1차원이니까.
arr1.size # 5: 원소 5개니까.
data2 = [[1, 2, 3., 4], [5, 6, 7, 8.]]
# nested list: list는 type 다른 원소를 가질 수 있지
arr2 = np.array(data2) # 2d array
data2 # [[1, 2, 3.0, 4], [5, 6, 7, 8.0]]
arr2 # array([[1., 2., 3., 4.], [5., 6., 7., 8.]])
# list는 실수&정수 혼용 가능, np.array는 모두 실수로 변환
arr2.dtype # dtype('float64')
# 실수형 data에 별도로 지정않는 경우 64기본.
arr2.ndim # 2: 2차원이니까
arr2.size # 8: 원소 8개니까
data3 = [[1, 2, 3., 4], [5+1j, 6, 7, 8.]]
# nested list: 정수 + 실수 + 복소수
arr3 = np.array(data3) # 2d array
data3 # [[1, 2, 3.0, 4], [5+1j, 6, 7, 8.0]]
arr3 # array([[1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j], [5.+1.j, 6.+0.j, 7.+0.j, 8.+0.j]])
# list는 numeric 혼용 가능, np.array는 모두 복소수로 변환
arr3.dtype # dtype('complex128')
arr3.ndim # 2: 2dim
arr3.size # 8
data4 = ['a', 'b']
arr4 = np.array(data4)
arr4.dtype # dtype('<U1'): 4byte 길이의 unicode 문자열
arr4.itemsize # 4
data5 = ['ab', 'b']
arr5 = np.array(data5)
arr5.dtype # dtype('<U2'): 8byte 길이의 unicode 문자열
data6 = ['abc', 'b']
arr6 = np.array(data6)
arr6.dtype # dtype('<U3'): 12byte 길이의 unicode 문자열
getsizeof(np.array([])), getsizeof(arr6)
# (96, 120), arr6에 각 12byte의 메모리 공간 할당됨
# 기본 array size=96.
- 결론, array는 각 data type이 모두 달라도, 가장 긴 문자열의 길이를 한 원소에 배정함.
- 복소수 + 정수 혼합 array : 복소수 * 원소수
- 긴 문자열 + 짧은 문자열 혼합 array: 긴 문자열원소수 * 4 * 원소수
- 문자열을 원소로 갖는 ndarray는 각 문자열의 원소 길이가 달라도, 모든 원소 중 가장 메모리가 긴 길이를 일률적으로 할당한다
Ndarray의 Axis
- Ndarray에 연산을 적용하면(벡터화 된 연산) 내부에서 iteration 과정 발생
- Axis: numpy 연산에서 iteration이 진행되는 방향
- 다차원 배열에서 반복과정이 적용되는 방향: axis
# 1차원 배열
import numpy as np
x = np.array([0, 1, 2, 3])
x # array([0, 1, 2, 3])
x.ndim # 1
# 0 - 1 - 2 - 3이 한 방향으로 있는거라고 생각하면 됨
# 2차원 배열
x = np.array([[0, 1, 2, 3], [4, 5, 6, 7]])
print(x.ndim) # 2: 0123 / 4567 0 - 4(axis2) & 0 - 1 - 2 - 3(axis1)
# 다차원 배열 원소들의 합 return
print(x.sum()) # 28
print(x.sum(axis=0)) # [4, 6, 8, 10], row
print(x.sum(axis=1)) # [6 22], col
# 3차원 배열
x = np.arange(24).reshape(3, 2, 4)
# reshape: 다차원 배열 shape 재구성.
# (3, 2, 4): Nr of elements (axis[0], axis[1], axis[2])
# sum 함수 사용시, axis라는 용어 없이 sum만 때려도 ok
x.sum(0) # array[[24, 27, 30, 33], [36, 39, 42, 45]]
x.sum(1)
x.sum(2)
- Question. x의 shape이 (3, 2, 4)인 경우
- shape of sum(0): (2, 4)
- shape of sum(1): (3, 4)
- shape of sum(2): (3, 2)
x[2, 0, 1] #17
# tuple 내 숫자의 index가 axis의 index 의미.
(axis0[2], axis1[0], axis2[1])
특별한 ndarray를 생성하는 내장 함수들
- numpy.arange()
- numpy.arange(start, stop[, step])
- range 객체와 return하는 element similar.
n = np.arange(5)
n # array([0, 1, 2, 3, 4])
n.dtype # dtype('int32')
n = np.arange(5, 0, -1)
n # array([5, 4, 3, 2, 1]_
# arange는 argument로 float 사용가능.
x = np.arange(0, 1, 0.1)
x # array([0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
x.dtype #
- numpy.linspace()
- np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)
- [start, stop] 구간에서 균등하게 나누어진 num개의 숫자들을 ndarray 객체로 return, start&stop(양끝점) 포함
- 양끝점을 포함하기 때문에 구간의 개수는 n-1개?
- endpoint=False: 우측 끝 점 미포함
x = np.linspace(1, 2, 5)
x # array([1. , 1.25, 1.5, 1.85, 2. ])
x = np.linpace(1, 2, 5, endpoint=False)
x # array([1. , 1.2, 1.4, 1.6, 1.8])
- numpy.logspace()
- np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0)
- [basestart, basestop] 구간에서 log 스케일로 균등하게 나누어진 num개의 숫자를 ndarray object로 return
- 양끝점을 포함하기 때문에 구간의 개수는 n-1개?
- logspace가 반환하는 값은 linspace가 반환하는 값들을 base의 지수로 사용한 값들을 반환하는 것.
np.logspace(1, 5, 5)
# array([1.e+01, 1.e+02, i.e+03, 1.e+04, 1.e+05])
np.logspace(0, 2, 3)
# array([1., 10., 100.])
- numpy.zeros()
- np.zeros(shape, dtype=Non, order='C')
- 모든 원소가 0.인 ndarray 객체를 반환
- default type=np.float64
x = np.zeros(5)
x # array([0., 0., 0., 0., 0.])
np.zeros((3, 4))
# 0으로 이루어진 3*4 matrix return.
x = np.zeros(5, dtype=np.int32) # dtype 지정 가능
np.zeros((3, 4, 2)) # 3차원 array
- numpy.zeros_like()
- np.zeros_like(a, dtype=None, order='K', subok=True, shpae=one)
- a와 shape, dtype이 같은 모든 원소가 0.인 ndarray 객체 반환
x = np.arange(5)
x, x.dtype, x.shape
# (array([0, 1, 2, 3, 4]), dtype('int32'), (5,))
- np.ones()
- np.ones(shape, dtype=None, order='C')
- 모든 원소가 1.인 ndarray 객체를 반환
- default type: np.float64
- np.ones_like()
- np.ones_like(a, dtype=None, order='K')
- np.full()
- np.full(shape, fill_value, dtype=None, order='C')
- 모든 원소가 fill_value인 ndarray object return.
- first argument = dimension of the array int: 1dim array, tuple: ndim array(shape)
- second argument = fulfill value, also determine data type
x = np.full(5, 3)
x # array([3, 3, 3, 3, 3])
x.dtype # dtype('int32')
- np.full_like()
- same shape and data type with a, return ndarray object with all elements are fill_value
a = np.full_like(x, 3.)
# x와 shape, data type이 같고, 3.0으로 채워진 array object return.
- np.eye()
- np.eye(N, M=None, k=0, dtype=<class 'float'>, order='C')
- 대각선이 모두 1이고, shape이 (N,M)인 2차원 ndarray return
- M이 생략되면 shape(N,N)
- k는 대각선의 위치를 결정하는 index
- int 넣어도 float이 기본 data type?
x = np.eye(3)
np.eye(4, k=1) # 4*4 matrix에서 k=0~3까지인데, k=4벗어나면
# 모든 원소의 값은 0
- np.diag()
- np.diag(v, k=0)
- 2차원 ndarray 객체에서 대각선을 추출해 1차원 ndarray 객체 return
- 1차원 ndarray 객체v를 대각선 원소로 갖는 2차원 ndarray 객체 반환
- k는 대각선의 위치를 결정하는 index
- 행렬 개수 다른 경우에도 OK
# 용법 1.
x = np.arange(16).reshape((4, 4))
np.diag(x) # array([0, 5, 10, 15])
np.diag(x, k=1) # array([1, 6, 11])
# 용법 2. 첫 번째 argument에 1차원 sequence 입력해서
# 2차원 ndarray 객체를 생성 가능.
np.diag([1, 2, 3])
# 대각선 원소들이 1, 2, 3이고 3*3인 2차원 ndarray 객체 생성
np.diag([1, 2, 3])[:, ::-1]
# axis0은 그대로 두고, axis1을 역순으로(100 020 003 > 001 020 300)
np.diag([1, 2, 3])[::-1, :]
# axis0을 역순으로(100 020 003 > 003 020 100)
np.diag([1, 2, 3])[::-1, ::-1]
# axis0,1을 역순으로(100 020 003 > 300 020 001)
Numpy 특수 다차원 배열: Random Module
- randint(low, high=None, size=None, dtype='l'): discrete uniform in [low, high)
- 난수 생성 알고리즘이 정해져있긴 함.
- 지정한 구간 내 균일한 분포 따르는 정규분포 내 정수 반환.
- 구간은 low, high라는 integer parameter로 지정
- low는 구간 포함, high는 구간 미포함
- low만 지정하고 high를 지정하지 않는 경우: 지정한 low = high, low=0
np.random.randint(5) # 1
# 0~5까지 4개 정수 가운데 하나 반환(p=1/5)
np.random.randint(5, 20)
# 5~19까지 15개의 정수 가운데 하나 반환(p=1/15)
# if size parameter > 0, array object being returned
a = np.random.randint(5, size=0)
a # array([], dtype=int32), 빈 ndarray.
a = np.random.randint(5, size=5)
a # array([1, 1, 0, 3, 4], dtype=int32)
np.random.randint(0, 10, (2, 3))
# size에 tuple 지정> tuple(2*3) matrix의 정수 난수 배열 return
- random(size=None): uniform in [0, 1)
- 난수의 확률분포는 균일분포.
np.random.random() # [0, 1) 사이 random 실수 반환
np.random.random(5) # [0, 1) 사이 random 실수 5개 반환해 array로
np.random.random((2, 3, 4) # shape이 size인, [0, 1) 사이 난수배열
- uniform(low=0.0, high=1.0, size=None)
- 균일분포 따르는 난수 발생
- 난수가 발생하는 범위는 low, high로 설정 가능
- randint의 low/high parameter는 int지만
- uniform의 low/high parameter는 실수이고 default 값이 0, 1이라는 점이 다름.
np.random.uniform() # [0, 1) 사이 random 함수 반환
np.random.uniform(1.5)
# 균일분포 따르는 0, 1.5 사이 난수 하나 발생
np.random.uniform(-1, 1)
# 균일분포 따르는 -1, 1 사이 난수 하나 발생
np.random.uniform(-1, 1, 4)
# 균일분포 따르는 -1, 1 사이 난수 4개 발생해 array로 return
np.random.uniform(-2, 2, (2, 3, 4))
# 균일분포 따르는 -2, 2 사이 난수 발생해 (2, 3, 4) array로 return
- normal(loc=0.0, scale=1.0, size=None): 평균이 loc, 표준편차가 scale인 정규분포
- 정규분포의 평균: loc, 표준편차: scale로 각 지정 가능
Numpy 특수 다차원 배열: Random Module
- choice(a, size=None, replace=True, p=None)
- sequence형 객체의 임의의 원소 반환.
- a = 정수인 경우 range(a)의 임의의 원소 하나 반환
- a = sequence, sequence 내 임이의 원소 하나 반환
728x90
'컴퓨터 > 프로그래밍' 카테고리의 다른 글
[Python] 파이썬 기초 11: Numpy(5, 6) (0) | 2024.09.06 |
---|---|
[Python] 파이썬 기초 10: Numpy(3, 4) (1) | 2024.09.06 |
[Python] 파이썬 기초 8: 함수(3, 4) (1) | 2024.09.04 |
[Python] 파이썬 기초 7: 함수(1, 2) (0) | 2024.09.04 |
[Python] 파이썬 기초 6: Set / Frozen Set 자료형 (0) | 2024.09.04 |