1.행렬이나 일반적으로 대규모 다차원 배열을 쉽게 처리 할 수 있도록 지원하는 파이썬의 라이브러리
2.데이터 구조 외에도 수치 계산을 위해 효율적으로 구현된 기능을 제공
출처 : 위키피디아
넘파이(numpy)를 사용하면 파이썬에서 행렬과 그 밖의 수치를 쉽고 빠르게 처리할 수 있다.
Numeric Python = numpy
통계 기반 머신러닝과 신경망 기반 딥러닝 = 행렬연산 + 통계 + 수치해석 등 도움이 된다.
넘파이랑 함께 사용할 수 있는 프로그램(패키지) = Scipy + Pandas + matplotlib
Scipy
: 수치 해석 패키지
Pandas
: 표(table) 연산 패키지
matplotlib
: 그래프 표시 처리 패키지
<<하이퍼 파라미터를 난수로 발생해서 대입할 때 사용할 내용의 함수를 넘파이 구현한다.>>
1차원 배열
list01 = [1,2,3,4]
print(list01)
[1,2,3,4]
2차원 배열
list02 = [[1,2,3,4], [5,6,7,8]]
[[1,2,3,4], [5,6,7,8]]
3차원 배열
list03 = [[[1,2,3,4], [5,6,7,8]],
[['가','나','다','라'],['마','바','사','아']]]
[[[1,2,3,4], [5,6,7,8]],[['가','나','다','라'],['마','바','사','아']]]
1.파이썬에서는 배열(array)이라는 데이터 형식을 지원하지 않으므로 리스트(list)
를 사용해 전통적인 의미의 배열을 사용
2.리스트는 포인터 기반 리스트 그래프 구조로 형성되어 컴퓨터 메모리 상에서 흩어져 있게 되지만, 넘파이 배열은 C 언어와 마찬가지로 컴퓨터 메모리의 연접 공간에 배열을 넣고 관리하기 때문에, ✔파이썬 리스트보다 처리 속도 면에서 비교할 수 없을 정도로 빠르다.
3.리스트를 만들 때 각 성분의 데이터 형식이 달라도 되지만, 넘파이 배열
에서는 💡각 성분의 데이터 형식이 같아야한다.
# (1) 넘파이 배열을 만들려면 먼저 리스트 형식으로 배열을 구성해 준다.
리스트형_배열 = [1, 2, 3, 4, 5] # 우변은 배열 정의 부분, =은 할당 연산.
print(리스트형_배열)
[1,2,3,4,5]
# (2) 그러고 나서 리스트 형식 배열을 넘파이 배열로 캐스팅한다.
넘파이형_배열 = np.array(리스트형_배열)
print(넘파이형_배열)
[1 2 3 4 5]
cmd에서의 값 = array([1, 2, 3, 4])
1.넘파이 배열의 데이터 형식은 'ndarray' 이다.
2.n차원 배열
(n-dimensional array)이라는 뜻을 지닌 이름
# [보충] 넘파이형 배열의 데이터 형식(data type, 자료형) 알아보기
type(넘파이형_배열)
<class 'numpy.ndarray'>
1차원 리스트 값을 바로 넣어 넘파이 형식 배열 형성하기
넘파이형_1차원_배열 = np.array([1, 2, 3, 4, 5])
print(넘파이형_1차원_배열)
print(type(넘파이형_1차원_배열))
[1 2 3 4 5]
<class 'numpy.ndarray'>
넘파이는 데이터 형식을 자동으로 변경 해준다.
넘파이형_1차원_배열02 = np.array([1, 2.1, 3.1, 4, 5])
print(넘파이형_1차원_배열02)
print(type(넘파이형_1차원_배열02))
print(넘파이형_1차원_배열02.tolist())
int와 float이 섞여있을 경우 float 형식으로 변형
[1. 2.1 3.1 4. 5. ]
<class 'numpy.ndarray'>
[1.0, 2.1, 3.1, 4.0, 5.0]
res = np.array(range(1,11))
print(res.mean(), res.var(), res.sum(), res.max(),res.min())
print(res)
print('tobytes = ', res.tobytes()) #byte로변환
print('tolist = ',res.tolist()) #list로 변환
res02 = res.tolist() #res복사하여 list로 변환
print(type(res02)) # list 타입
mean() = 중간 값
var() = 분산
sum() = 합
max() = 최대 값
min() = 최소 값
5.5 8.25 55 10 1
[ 1 2 3 4 5 6 7 8 9 10]
tobytes = b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00'
tolist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
<class 'list'>
넘파이형_2차원_배열 = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(넘파이형_2차원_배열)
[[ 1 2 3 4 5][ 6 7 8 9 10]]
넘파이형_3차원_배열 = np.array([[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]], [[1.0, 2.0, 3.0, 4.0, 5.0], [6.0, 7.0, 8.0, 9.0, 10.0]]])
print(넘파이형_3차원_배열) # 각 수치가 모두 부동소수점 형식으로 통일되었다는 점에 주목하자.
[[[ 1. 2. 3. 4. 5.][ 6. 7. 8. 9. 10.]]
.
[[ 1. 2. 3. 4. 5.][ 6. 7. 8. 9. 10.]]]
넘파이 형식으로 된 배열을 보통 넘파이 배열
이라고 부른다.
print(넘파이형_1차원_배열.shape)
print(넘파이형_2차원_배열.shape)
print(넘파이형_3차원_배열.shape)
(5,) = 5행
(2, 5) = 2열,5행
(2, 2, 5) = 2열, 2열, 5행
print(넘파이형_1차원_배열.ndim)
print(넘파이형_2차원_배열.ndim)
print(넘파이형_3차원_배열.ndim)
1
2
3
ndim = 배열 차원 확인(몇 차원인가?)
test01 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[]]])
print(test01.ndim)
test01은 몇차원일까?
.
답은 2차원이다.
빈 리스트는 포함하지않는 것 같다.
print(넘파이형_1차원_배열.dtype)
print(넘파이형_2차원_배열.dtype)
print(넘파이형_3차원_배열.dtype) # 각 원소의 데이터 형식이 float 형식이라는 점에 주목 <- 알아둘 것!
# 신경망의 뉴론간의 연결을 가중치로 표현을 실수로 한다. 가중치는 신경세포간의 연결 신호 강도 비율 이다. 0.1234 -> 1234 64bit-> 16bit 메모리 1/4로 줄이면서 신경망을 구성할 수 있다.
int64는 정수형(64비트로 표현), float64는 소수점 수(실수형, 64비트로 표현)
int64
int64
float64
.
cmd : int32 (로 출력되서 나왔다.)
float은 동일
부울_배열 = np.array([True, False, True, 1, 0])
print(부울_배열) # (1 0 1 1 0) -> 벡터 연산 (컬러이미지) -> 흑백이미지로 변환 -> 연산작업 / 컬러이미지 -> 분할(28*28) -> 연산
# 특징 잡기 / 노이즈 ( None / 중복데이터 ) 제거할 때 사용
print(부울_배열.shape)
print(부울_배열.dtype)
'[1 0 1 1 0]'
(5,)
int64
상삼각행렬, 하 삼각행렬등을 활용한 행렬 연산(특히 영상 처리)에 자주 쓰여요 그리고 행렬에서 특정 자료를 찾아 내거나 (인덱싱) 뽑아내거나 (슬라이싱) 해야 할 때 많이 사용한다.
문자열_배열 = np.array([["우리는 A반", "우리는 B반"],
["Class 1", "Class 2"]])
print(문자열_배열)
print(문자열_배열.shape)
print(문자열_배열.dtype) # 문자열의 경우 데이터 형식이 상황에 따라 다르다.
# 하지만 의미가 없다.
[['우리는 A반' '우리는 B반']
.
['Class 1' 'Class 2']]
(2, 2)
< U7
x = np.array ([1.,2,3])
x.dtype
x= np.array([1,2,3], dtype='f')
x.dtype # float32
#한 데이터 형식에서 다른 데이터 형식으로 정의된 배열의 데이터 형식을 변경하는 메소드 astype
x= x.astype(np.float64)
x.dtype
dtype('float64')
수치 처리를 하다 보면 0으로 채워진 배열이나 1로만 채워진 배열이나 수열로 이뤄진 배열이 필요할 때가 있다.
넘파이를 사용하면 이런 배열을 아주 쉽게 형성할 수 있다.
# 0으로만 이뤄진 1차원 배열
print(np.zeros(5)) # 💡따로 지정하지 않으면 float 형으로 형성된다.
[0. 0. 0. 0. 0.].
default : float
영행렬, 단위행렬(1로 채워진 행렬) 1차원 배열 = 벡터 / 2차원 행렬 / 3차원은 텐서
0이 무려 5개!!!
print(np.zeros(5, dtype=int)) # 데이터 형식을 따로 지정할 수 있다.
[0 0 0 0 0].
dtype = int64
print(np.zeros((2, 2), dtype=int))
[[0 0]
.
[0 0]]
print(np.zeros((2, 2, 2), dtype=int))
[[[0 0][0 0]]
.
[[0 0][0 0]]]
참고로 메모리 크기까지도 지정할 수 있다.
이에 대해서는 넘파이 공식 매뉴얼을 보자.
팔비트_배열 = np.zeros(5, dtype=np.ubyte)
print(팔비트_배열)
print(팔비트_배열.dtype)
[0 0 0 0 0].
uint8
# 1로만 이뤄진 2차원 배열
print('---2차원---\n',np.ones((5, 3)))
print('---1차원---\n',np.ones((5)))
print('---3차원---\n',np.ones((5, 3, 3)))
dtype = float64
3차원의 값 = 5개의배열 3행 3열
코드가 너무 길어서 생략
# 종료값만 지정하는 경우(시작 값은 0, 종료 값은 9)
print(np.arange(10)) #수열로 이루어진 배열
[0 1 2 3 4 5 6 7 8 9].
dtype = int64
print(np.arange(2, 10))
[2 3 4 5 6 7 8 9].
print(np.arange(2, 10, 2)) # 2에서 9까지(10의-1) 2스텝씩
[2 4 6 8].
넘파이의 배열은 수학의 행렬(또는 텐서)을 표현하기 위한 것이므로
넘파이에서 배열 연산을 한다는 것은 행렬 연산을 한다는 것과 거의 같다
일 = np.ones((2, 2))
print(일)
[[1. 1.]
.
[1. 1.]]
이 = 일 + 일
print(이)
[[2. 2.]
.
[2. 2.]]
영 = 일 - 일
print(영)
[[0. 0.]
.
[0. 0.]]
사 = 이 * 이
print(사)
#곱셈 = 스칼라 곱
[[4. 4.]
.
[4. 4.]]
이 = 사 / 이
print(이)
[[2. 2.]
.
[2. 2.]]
나머지 = 사 % (사 - 일)
print(나머지)
[[2. 2.]
.
[2. 2.]]
하다 보면 dtype이 float이라는 것을 눈치 챘을 것이다.
나머지 = 사 % (사 - 일)
print(나머지)
[[1. 1.]
.
[1. 1.]]
기본적으로 크기가 같은 배열끼리 연산을 할 수 있고, 크기가 서로 다른 배열이라면 브로드캐스팅(broadcasting) 기능을 사용해 연산
큰_일 = np.ones((2, 2)) # 배열의 크기 (2, 2)
print(큰_일)
[[1. 1.]
.
[1. 1.]]
작은_일 = np.ones((2)) # 배열의 크기 (2,)
print(작은_일)
[1. 1.].
print(큰_일 + 작은_일) # 작은_일의 배열 크기가 (2, 2)로 조정되고
# 💡확장된 부분을 기존 배열 원소값으로 채운 후 연산
[[2. 2.]
.
[2. 2.]]
행렬에 스칼라값을 가지고 연산할 수 있듯이 넘파이 배열에 스칼라 값을 가지고 연산
print(사 * 2)
[[8. 8.]
.
[8. 8.]]
print(사 - 4)
[[0. 0.]
.
[0. 0.]]
넘파이 배열에서 인덱싱을 하는 방법은 파이썬에서 리스트 등을 대상으로 인덱싱을 하는 방법과 같다
# 1차원 배열 인덱싱
일차원_배열 = np.array([2, 4, 8, 10])
print(일차원_배열
[ 2 4 8 10].
print(일차원_배열[0]) # 스칼라 값이 나온다.
2
데이터 = 일차원_배열[0]
type(데이터)
numpy.int64
print(일차원_배열[:1]) # 행렬 값이 나온다.
print('\n')
[2].
데이터2 = 일차원_배열[:1]
type(데이터2)
numpy.ndarray
print(일차원_배열[-1]) # 스칼라 값이 나온다.
print(일차원_배열[-1:]) # 💡행렬 값이 나온다.
print('\n')
print(일차원_배열[2:5])
print(일차원_배열[:3])
print(일차원_배열[1:]) # start : end-1 : step
10
[10]
.
.
[ 8 10][2 4 8]
[ 4 8 10]
이차원_배열 = np.array([[2, 4, 8, 10], [3, 5, 7, 9]])
print(이차원_배열[1, 1]) # 2행 2열 값이 출력된다.
print(이차원_배열[0, 3]) # 1행 4열 값이 출력된다.
5
10
print(이차원_배열[:, 2]) # 각 행의 3열 값이 출력된다.
print(이차원_배열[1, :]) # 2행이 모두 출력된다.
[8 7].
[3 5 7 9]
# 부울 값 기반 인덱싱에 쓸 배열들을 준비한다.
모수_배열 = np.array([1, 2, 3, 4, 5])
print(모수_배열)
부울_배열_1 = np.array([True, False, True, False, True])
부울_배열_2 = np.array([1, 0, 1, 0, 1]) # 💡인덱싱을 할 때는 부울 값을 1, 0으로 표기하면 안 된다.
# 이것은 '정수 인덱싱'이라고 부르는 방법이기 때문이다.
print(부울_배열_2)
print(모수_배열[부울_배열_1]) # 🔍바른 방식이다.
print(모수_배열[부울_배열_2]) # 🔍문제가 생긴다.
#~~~~~~! 중요하다
[1 0 1 0 1].
[1 3 5]. = True만 출력
[2 1 2 1 2] = 인덱스가 출력
모수_배열 = np.array([1, 2, 3, 4, 5])
정수형_인덱스_배열 = np.array([0, 2, 3]) # 각 원소가 인덱스 값으로 쓰인다.
print(모수_배열[정수형_인덱스_배열])
# 출력을 해 보면 모수_배열의 0번째 원소(즉, 1),
# 2번째 원소(즉, 3), 3번째 원소(즉, 4)가 출력되는 점을 볼 수 있다.
[1 3 4] = 정수 인덱싱
넘파이 배열 슬라이싱도 리스트 슬라이싱과 크게 다르지 않다.
이차원_배열 = np.array([[2, 4, 8, 10], [3, 5, 7, 9]])
print(이차원_배열[0, :]) # 첫 번째 행 전부
print(이차원_배열[:, 0]) # 첫 번째 열 전부
print(이차원_배열[0, 1:]) # 첫 번째 행의 두 번째 열부터 마지막 열까지
[ 2 4 8 10].
[2 3].
[ 4 8 10]
# 두 배열을 연산할 때 배열간의 차원이 다르게 지정되어 크기를 맞추게 된다. = ValueError
# 브로드 캐스트 배열의 각 차원의 크기는 입력 배열에서 해당 차원의 가장 큰 값과 동일하다.
# 입력된 배열은 각 차원의 크기가 입력의 큰 배열의 크기와 같고 확장된 크기로 계산된다.
# ex) 결손 값(null) 포함한 노이즈 값을 처리할 때 다양한 값들로 값의 균형을 맞추어 채우게 되는 경우가 발생된다.
# ex) 데이터의 학습 결과가 모두 100%에 근접한 결과를 초래하게 되면 역순으로 파이프라인을 따라 값을 조정해서 재학습(미분)을 기준으로 하게 된다.
# 이 때 값을 조정하는 부분에서 난수를 채울 때 사용한다. ( 100 = 100% / 데이터 줄여봐 , 데이터 늘려봐 ... )
# ex) 흑백 이미지 노이즈
# 코드를 실행할 때마다 행렬 원소 값이 달라진다.
난수_배열 = np.random.randn(5, 5) # 2차원
print(난수_배열)
난수_배열 = np.random.randn()
난수_배열
5행5열로 난수 생성
1행 난수생성
a = np.random.randint(0,10,(2,1,3)) # 0 : 10-1까지 , (면,행,열) 1,3개짜리의 2개
b = np.random.randint(0,10,(3,1)) # 3행 1열
print('a:\n',a)
print('\n a.shape : ',a.shape)
print('b:\n',b)
print('\n b.shape : ',b.shape)
print('a:\n',a)
print('\n a.shape : ',a.shape)
.
print('b:\n',b)
print('\n b.shape : ',b.shape)
.
.
a:
[[[6 1 6]]
.
[[3 7 9]]]
.
a.shape : (2, 1, 3)
b:
[[8][3]
[7]]
.
b.shape : (3, 1)
c= a+b
print('a+b:\n',c)
print('\n np.shape :',c.shape)
a와b 의 난수들 끼리의 합 출력
np.shape : (2, 3, 3)
print(b)
print(np.newaxis)
print('\n O.S b.shape :',b.shape)
b_ex = b[np.newaxis, :,:] # 차원 값 생성
print('\n Added new axis to the top :',b_ex.shape)
print(b_ex)
b_ex02 = b[:,np.newaxis,:] #차원 값 생성( 순서는 마음대로 지정할 수 있는 것 같다.)
print('\n Added new axis to the top :',b_ex02.shape)
print(b_ex02)
b 출력
None
.
O.S b.shape : (3, 1)
. Added new axis to the top : (1, 3, 1)
.
b_ex 출력 = 2차원
.
Added new axis to the top : (3, 1, 1)
b_ex02 출력 = 3차원
절댓값_배열 = np.abs(난수_배열)
print(절댓값_배열)
절댓값 출력
print(np.sqrt(절댓값_배열), '\n') # 제곱근 구하기
print(np.square(절댓값_배열), '\n') # 제곱 구하기
print(np.exp(절댓값_배열), '\n') # 자연 대수 구하기
print(np.log(절댓값_배열), '\n') # 자연 로그 구하기
print(np.log10(절댓값_배열), '\n') # 상용 로그 구하기
print(np.log2(절댓값_배열), '\n') # 밑이 2인 로그 구하기
새_난수_배열 = np.random.randn(2, 2)
print(np.cos(새_난수_배열), '\n') # 코사인 함수
print(np.sin(새_난수_배열), '\n') # 사인 함수
print(np.tan(새_난수_배열), '\n') # 탄젠트 함수
# 이 밖에도 sinh, cosh, tanh, arcsin, arccos, arctan, arcsinh, arccosh, arctanh가 구비되어 있다.
# 연산에 쓸 정수 행렬 두 개를 생성한다.
# 예측값 : 빈도 ,특정범위의 숫자, 발생확률, 클래스 등이 될 수 있다. (반드시 데이터 변형작업 = 캘리브레이션 (calibration))
# ML 모델은 데이터에서 특정 샘플에 대한 특정 값이 라고 예측한다.
# x축은 예측 값, y축은 실제 값으로 그려낸다.
행렬_1 = np.random.randint(5, size=(5, 5)) # 0 ~ 4 사이 난수 생성 균등 분포 (최대값 , 사이즈 )
행렬_2 = np.random.randint(5, size=(5, 5)) # 정수형 균등 분포를 형성한다.
print(행렬_1)
print('\n')
print(행렬_2)
print(np.add(행렬_1, 행렬_2), '\n') # 덧셈
print(np.subtract(행렬_1, 행렬_2), '\n') # 뺄셈
print(np.multiply(행렬_1, 행렬_2), '\n') # 곱셈
print(np.divide(행렬_1, 행렬_2)) # 나눗셈 ㅠ infinit = 무한대 # nan a number = 수가 아니다.
#중간에 0으로 나눈값이 존재 한다.
[[0.66666667 1.5 1.5 3. 1. ][1.33333333 0.5 1. 1.5 0.5 ]
[0.5 0. inf 1.5 1. ][1. inf 1. 1.33333333 0. ]
[0. 1. 1. 0. 1.5 ]]
값 중에 inf = infinit 즉 무한대를 뜻함,
nan = 수가 아님
💡행렬 간에 나눗셈을 할 때는 0으로 나누는 경우 등이 생길 수 있다
print(np.maximum(행렬_1, 행렬_2), '\n') # 최댓값
print(np.minimum(행렬_1, 행렬_2), '\n') # 최솟값
넘파이를 사용하면 행렬에 대한 각종 통계량(stats)
을 쉽게 알 수 있다
머신러닝, 딥러닝 = 수리통계 , 통계학 , 수학
내장 = embedding
Guassian model = 가우스 모형 , 가우스 혼합
행렬 = np.random.randint(20, size=(5, 5))
print(행렬)
0 ~ 19 사이 난수 생성
print(np.sum(행렬), '\n') # 전체 성분의 합
print(np.sum(행렬, axis = 0), '\n') # 행 성분의 합
print(np.sum(행렬, axis = 1), '\n') # 열 성분의 합
print(np.mean(행렬), '\n') # 전체 성분의 평균
print(np.var(행렬), '\n') # 전체 성분의 분산
print(np.std(행렬), '\n') # 전체 성분의 표준편차
print(np.median(행렬), '\n') # 전체 성분의 중위수
print(np.percentile(행렬, 0), '\n') # 전체 성분의 최솟값
print(np.percentile(행렬, 25), '\n') # 전체 성분의 1/4분위 위치 값
print(np.percentile(행렬, 50), '\n') # 전체 성분의 2/4분위 위치 값
print(np.percentile(행렬, 75), '\n') # 전체 성분의 3/4분위 위치 값
print(np.percentile(행렬, 100), '\n') # 전체 성분의 4/4분위 위치 값 = 최댓값
print(np.max(행렬), '\n') # 전체 성분의 최댓값
print(np.min(행렬), '\n') # 전체 성분의 최솟값
시드(seed)란 우리 말로 하면 '씨앗'으로 번역될 수 있는 말로, 여러 차례에 걸쳐 난수를 생성할 때 매번 같은 난수가 생성될 수 있도록 하기 위한 시촛값에 해당 이 값을 정해두면 코드가 새로 실행될 때마다 난수가 바뀌지 않기 때문에, 코드가 항상 동일한 결과를 낼 수 있게 할 수 있다. 즉, 코드의 재현성에 필수인 기능이다.
# 매번 다른 결과가 나온다.
print(np.random.rand(5), '\n')
print(np.random.rand(5), '\n')
# 매번 같은 값이 나온다. 모의 데이터 실험시 매번 모의 데이터가 같아야 비교를 한다.
np.random.seed(0) # 시드 값을 정할 때는 0 이상인 정수로 지정한다.
print(np.random.rand(5), '\n')
np.random.seed(0)
print(np.random.rand(5), '\n')
[0.5488135 0.71518937 0.60276338 0.54488318 0.4236548 ]
.
[0.5488135 0.71518937 0.60276338 0.54488318 0.4236548 ]
두 난수들이 같은 값으로 나온다.
# 크기가 5인 일차원 균일 배열(즉, 벡터 또는 일차 텐서) 형성
# 이때 각 성분의 범위는 0 ~ 1
일차원_균일분포_배열 = np.random.rand(5)
print(일차원_균일분포_배열)
print('\n')
# 이때 각 성분의 범위는 0 ~ 1
이차원_균일분포_배열 = np.random.rand(5, 5) #균일 분포 randn() -> normal =정규분포
print(이차원_균일분포_배열)
print(np.random.randint(20, size = 20), '\n') # 0 ~ 19 사이 정수 균일분포 형성
print(np.random.randint(20, 40, size = 20), '\n') # 20 ~ 39 사이 정수 균일분포 형성
print(np.random.randint(20, 40, size = (4, 5)), '\n') # 20 ~ 39 사이 2차원 균일 분포 형성 size = 4행 5열
print(np.random.randint(10, size = (2,3,4)))
0~9까지 2면 3행 4열로 난수생성
일차원_표준정규분포_배열 = np.random.randn(5) # 크기가 5인 벡터
print(일차원_표준정규분포_배열)
이차원_표준정규분포_배열 = np.random.randn(5, 5) # 크기가 5X5인 행렬 형성
print(이차원_표준정규분포_배열)
표본추출(sampling)이라는 말을 컴퓨터과학을 포함해 다양한 이과/공과 계열 학문에서는 샘플링
이라고 부르는 경우도 많지만, 향후 인공지능 구현 시에 통계학에서 유래한 개념들이 많이 쓰이므로(딥러닝도 마찬가지) 앞으로 표본추출
이나 표집
이라고 부른다(어감에 차이가 있지만 무시). 임의표본추출(random sampling)
,
즉 임의표집이란 모집단(population)
에서 아무렇게나 표본(sample)
을 선택해추출(sampling)
한다는 말
표본추출_배열 = np.random.choice(10, 5) # 모집단은 0~9, 벡터 크기는 5
print(표본추출_배열)
표본추출_배열 = np.random.choice(10, (5, 5)) # 모집단은 0~9, 행렬 크기는 5X5
print(표본추출_배열)
print(표본추출_배열.flatten()) # 행렬 -> 벡터 평탄화 flattening 한줄로 늘여 뜨린다.
[9 0 8 1 6 9 7 1 4 9 8 6 7 5 7 8 5 1 4 7 8 7 7 9 9] 한줄로 출력한다.
# ***위에 출력되지 않은 값이 전혀 나오지 않는다는 점을 잘 살펴보자.***
새_표본추출_배열 = np.random.choice(표본추출_배열.flatten(), (3, 5)) # 모집단은 0~9, 행렬 크기는 3X5
print(새_표본추출_배열)
[[5 4 7 0 2].
[0 7 4 3 2].
[9 1 6 4 0]]
행렬의 크기를 재정의 하는 느낌
#choice()이 세번째 매개 인자는 확률이 되는 경우를 100%로 나누어서 인덱스로 관리한다.
# 모집단은 0~2, 행렬 크기는 10 X 10
# p(0)=0.0, p(1)=0.9, p(2)=0.1
표본추출_배열 = np.random.choice(3, size=(10, 10), p=[0.1, 0.8, 0.1]) #0이 뽑힐 확률 10% 1이 출력될 확률은 80% 2가 출력될 확률은 10%
print(표본추출_배열)
0~2까지 10행10열 형으로 0=10%, 1=80%, 2=10% 확률로 추출하여 출력한다.
출력 결과를 보면 0이 표본추출되지 않고 주로 1이 표본추출되며, 간간이 2가 표본추출된 것을 볼 수 있습니다.
우리는 앞에서 정수 성분으로 이뤄진 분포를 형성해 본 적이 있다. 그런데 성분의 개수가 굉장히 많다면 해당 분포에서 다시 데이터를 추출해 탐색해 보는 일이 필요
파이썬 -> 넘파이 . 파이썬 ->머신러닝/ 딥러닝 -> 머신 -> 딥러닝
새_분포 = np.random.randint(100, size=(5, 95)) # 모집단 0~ 99 에서 중복 추출 후 새로운 분포를 만들자 정수형 균일 분포 , 복원 추출
print(새_분포)
# 주의: 차원축소 방법에서 말하는 고윳값(eigenvalue)과 혼동하지 말 것
# 데이터 -> 수치 -> 카테고리 별로 -> 분류 ->
성분_값, 성분별_개수 = np.unique(새_분포, return_counts=True)
print(성분_값)
print(성분별_개수) # 자연어 처리시에 추출 중복되지 않은 어절
성분값 = 0~99까지 나열
성분별개수 = 중복되지 않은 값
# return_counts를 지운다.
성분_값 = np.unique(새_분포)
print(성분_값)
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 65 66 67 68 69 70 71 72 73
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 97 98]
# list 함수를 사용해 행렬(넘파이 배열)을 리스트로 캐스팅하고
# zip 함수를 사용해 두 리스트를 튜플 형태로 짝 지은 다음에
# 다시 리스트 형태로 만들어(파이썬 3에서는 이렇게 한 단계 더 거쳐야 함)
# 출력한다.
print(list(zip(list(성분_값), list(성분별_개수))))
[(0, 8), (1, 4), (2, 3), (3, 5), (4, 4), (5, 9), (6, 9), (7, 4), (8, 3), (9, 3)...]
수치 처리를 하다 보면 난수 형성만으로는 충분하지 않을 때가 있다. 우리가 만든 데이터나 난수를 아무렇게나 섞어야 할 때가 있다. 넘파이의 numpy.random.shuffle()
을 사용하면 이렇게 할 수 있다
# 먼저 1차원 배열을 만들어 보자.
배열 = np.arange(10)
print(배열, '\n')
# 그리고 이 행렬을 섞어 보자.
np.random.shuffle(배열)
print(배열, '\n')
[0 1 2 3 4 5 6 7 8 9]
.
[0 4 5 1 3 2 9 8 6 7]
배열 = np.arange(25).reshape(5, 5) # 5x5 2차원으로 변경
print(배열, '\n')
np.random.shuffle(배열) # 셔플
print(배열, '\n')
[[ 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]]
.
[[20 21 22 23 24].
[ 5 6 7 8 9].
[ 0 1 2 3 4].
[10 11 12 13 14].
[15 16 17 18 19]]
# 이럴 때는 배열을 1차원으로 만들어(평탄화를 해서) 섞은 다음에
# 다시 3차원 꼴로 편성하는 요령을 발휘하면 된다.
일차원_배열 = 배열.flatten()
print(일차원_배열, '\n')
np.random.shuffle(일차원_배열)
print(일차원_배열, '\n')
이차원_배열 = 일차원_배열.reshape(5, 5)
print(이차원_배열, '\n')
배열을 1차원(벡터)로 변경
셔플
배열 2차원으로 재정의
# 그 밖의 연산에 쓸 새 난수를 생성해 두자.
새_난수_배열 = np.random.randn(3, 3)
print(새_난수_배열)
3행3열 난수생성
# 음수는 -1, 영은 0, 양수는 1로 나옴
print(np.sign(새_난수_배열))
print(np.ceil(새_난수_배열), '\n') # 소수점 이하 첫 번째 자리에서 올림
print(np.floor(새_난수_배열), '\n') # 소수점 이하 첫 번쨰 자리에서 내림
# 먼저 NaN이 나올 만한 연산을 한다.
print(np.sqrt(새_난수_배열), '\n')
# NaN 성분을 알아낸다.
print(np.isnan(np.sqrt(새_난수_배열)), '\n')
[[ nan nan 0.15117834].
[ nan nan 1.06074929].
[0.74970285 nan 0.10679901]]
.
[[ True True False].
[ True True False].
[False True False]]
.
nan 이면 True 반환
[ : 1차원
[[ : 2차원
[[[ : 3차원
np.array() : 넘파이 배열형성
1차,2차,3차원 가능
shape : 넘파이 배열의 크기 확인 (행렬의 모양)
ndim : 넘파이 배열의 차원 확인
dtype : 데이터 형식 확인 ex) int64 , float64
np.zeors() : 0으로만 이뤄진 배열 형성 , dtype : (default) float형식
np.ones() : 1로만 이뤄진 배열 형성 , dtype : (default) float형식
np.arange() : 수열로 이뤄진 배열 형성
np.random.rand() : 난수 생성 ex) 디폴트는 1차원 ,2,2 = 2차원 난수 생성
np.abs() : 절댓값 연산
np.choice : 표본 추출
np.flatten : 행렬을 백터로 만듬 (평탄화)
zip : 튜플로 묶는다.
브로드캐스팅 : 같은 배열끼리 연산
스칼라 연산 : 넘파이 배열에 스칼라 값을 가지고 연산
배열 인덱싱 : 넘파이 배열에서 인덱싱 (파이썬의 인덱싱과 같음)