import numpy as np
'''
넘파이 배열 : 넘파이에서 텐서 데이터를 다루는 객체
텐서(TENSOR) : 선형대수의 데이터 배열
-RANK(랭크)에 따라 이름이 다름
ex) RANK 1 = 벡터
RANK2 = 행렬
괄호가 없는건 스칼라값, 괄호 한개는 벡터값
7 -- > 스칼라
[10,10] --> 벡터 1차원 텐서
[[10,10],[15,15]] --> 행렬 2차원 텐서
[[[1,5,9],[2,6,10]],[[3,7,11],[4,8,12]]] --> 3차원 텐서
----------------------------------------------------------
배열 생성
-np.array 함수 사용하여 배열 생성
[실습]
import numpy as np
test_array = np.array([1,4,5,8],float)
-매개변수 1 : 배열 정보
-매개변수 2 : 넘파이 배열로 표현하려는 데이터 타입
----------------------------------------------------------
'''
#test_array = np.array([1,4,5,'8'],float) --> 문자열 8 또한, 실수형으로 변환된다.
test_array = np.array([1,4,5,8],float)
# [1. 4. 5. 8.]
print(test_array)
# 요소에 대한 데이터 타입 확인 <class 'numpy.float64'>
print(type(test_array[3]))
# 배열 전체의 데이터 타입 변환 float64
print(test_array.dtype)
# 배열의 구조(shape)를 반환함 1차원 벡터의 자릿수 (4,) 만약, 2차원이라면 (4,N,) 이런식으로 표현된다.
print(test_array.shape)
'''
파이썬 리스트와 넘파이 배열의 차이점
----------------------------------------------------------
-텐서 구조에 따라 배열 생성
--배열의 모든 구성 요소에 값이 존재해야 함
[실습]
test_list = [[1,4,5,8],
[1,4,5]]
np.array(test_list,float) # Value Error 2행4열이기 때문에, 1,4,5 부분에 값을 하나 더 추가해야한다.
동적 타이핑을 지원하지 않음
-하나의 데이터 타입만 사용
----------------------------------------------------------
데이터를 메모리에 연속적으로 나열
-각 값 메모리 크기가 동일
-검색이나 연산속도가 리스트에 비해 훨씬 빠름
'''
'''
----------------------------------------------------------
배열의 구조 확인
'''
matrix = [[1,2,5,8],[1,2,5,8],[1,2,5,8]]
# 2차원 행렬 (3,4) 출력 --> 3행 4열 이다.
print(np.array(matrix,int).shape)
#3차원 행렬
tensor_rank3 = [
[[1,2,5,8],[1,2,5,8],[1,2,5,8]],# 1
[[1,2,5,8],[1,2,5,8],[1,2,5,8]],# 2
[[1,2,5,8],[1,2,5,8],[1,2,5,8]],# 3
[[1,2,5,8],[1,2,5,8],[1,2,5,8]] # 4
]
# (4,3,4) 행의세트?(4개) , 3행 4열
print(np.array(tensor_rank3,int).shape)
# 전체 요소의 개수 48개
print(np.array(tensor_rank3,int).size)
# 배열의 차원수 3
print(np.array(tensor_rank3,int).ndim)
'''
----------------------------------------------------------
매개변수 Dtype로 넘파이 배열의 데이터 타입 지정
-변수가 사용하는 메모리 크기가 정해짐
----------------------------------------------------------
int로 설정할 경우, 정수로 출력
float로 설정 할 경우 , 소수점 . 이 붙어서 출력한다 .
#dtype INT로 설정시 소수점 뒷자리는 버림후, 출력
np.array([[1,2,3,4,5],[4,5,6.5]],dtype=int)
OUT : array([[1,2,3],[4,5,6]])
----------------------------------------------------------
import sys
np.array([[1,2,3.5],[4,5,6.5]], dtype =np.float64).itemsize
각 데이터가 가지고 있는 사이즈값 예) 1의 사이즈는 8
OUT : 8
#float32로 수정
np.array([[1,2,3.5],[4,5,6.5]], dtype =np.float32).itemsize
OUT : 4
----------------------------------------------------------
reshape 함수로 배열의 구조를 변경하고 랭크 조절
[실습]
'''
x = np.array([[1,2,5,8],[1,2,5,8]])
#(2,4) 출력 2행 4열 2차원
print(x.shape)
# 1차원 변경
x.reshape(-1)
# ARRAY: [1 2 5 8 1 2 5 8]
print('ARRAY:',x.reshape(-1))
a = np.array(range(8))
# [0 1 2 3 4 5 6 7] 출력
print(a)
## 4행 2열로 만든다. 오류 출력 데이터 사이즈 개수(8개)가 맞아야한다.
print(a.reshape(4,2))
#출력
'''
[[0 1]
[2 3]
[4 5]
[6 7]]
-----------------------------------------------------------
'''
#2행, -1을 하면 알아서 생성되게끔 한다.
print('2행, 열은 자동 생성',a.reshape(2,-1))
'''출력 결과: 2행 , 4열
[
[0 1 2 3]
[4 5 6 7]
]
'''
#행의 세트 : 2 , 2행 , 열은 알아서 생성
print(a.reshape(2,2,-1))
'''출력결과 : 행 세트 : 2 , 2행 2열
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
-----------------------------------------------------------
'''
'''
flatten 함수는 데이터 그대로 1차원으로 변경
-데이터의 개수는 그대로 존재
-배열의 구조만 변한다 .
[실습]
'''
x = np.array(range(8)).reshape(2,2,2)
print(x)
'''출력: 2세트 , 2행, 2열 (3차원)
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
'''
#출력 1차원으로 변환
print('flatten:',x.flatten())
print('reshape:',x.reshape(-1))
'''출력: [0 1 2 3 4 5 6 7]
'''
'''
-----------------------------------------------------------
<인덱싱과 슬라이싱>
넘파이 배열의 인덱스 표현에는 ','을 지원
-'[행][열]' 또는 '[행,열]' 형태
3차원 텐서 이상에는 shape에서 출력되는 랭크 순서대로 인덱싱에 접근
[실습1]
-----------------------------------------------------------
'''
x = np.array([[1,2,3],[4,5,6]],int)
print(x)
'''
#출력
[[1 2 3]
[4 5 6]]
[실습2]
'''
#출력 : 1
print(x[0][0])
#출력 : 3
print(x[0,2])
# x의 0,1을 100으로 변경
x[0,1] = 100
print('array:',x)
'''
array: [[ 1 100 3]
[ 4 5 6]]
''''''
-----------------------------------------------------------
<슬라이싱>
슬라이싱 : 인덱스를 사용하여 리스트 일부를 잘라내어 반환
넘파이 배열은 행과 열을 나눠 슬라이싱할 수있음
'''
x = np.array([[1,2,3,4,5],[6,7,8,9,10]],int)
#전체 행의 2열 이상
print(x[:,2:])
''' 출력결과:
[[ 3 4 5]
[ 8 9 10]]
'''
#1행의 1열 ~ 2열
print(x[1,1:3])
''' 출력결과:
[7 8]
'''
#1행~ 2행까지, 실제론 3행이 없기 때문에 2행까지
print(x[1:3])
'''출력결과
[[ 6 7 8 9 10]]
-----------------------------------------------------------
''''''
< STEP >
증가값 : 리스트에서 데이터의 요소를 호출할 때 데이터를 건너뛰면서 반환
'[시작 인덱스:마지막 인덱스:증가값]' 형태
[실습]
'''
#0부터 14까지 3행으로 5씩 나눈다
x = np.array(range(15),int).reshape(3,-1)
print(x)
'''출력결과
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
''''''
[실습] 1씩 건너뛰면서 추출 하기
'''
x = np.array(range(15),int).reshape(3,-1)
#모든행을 포함하고, 0부터 끝까지 2씩 추출
print(x[:,0::2])
'''
0,3,10,13 추출 하기
'''
#전체에서 2칸씩 건너뛰고, 전체에서 3칸씩 건너뛰면
print(x[::2, ::3])
'''
-----------------------------------------------------------
< 배열 생성 함수 arange >
-range 함수와 같이 차례대로 값을 생성
-'(시작 인덱스,마지막인덱스,증가값)' 으로 구성
-range함수와 달리 증가값에 소수점 입력해도 값을 생성할 수 있음
-소수점 값을 주기적으로 생성할때 유용
'''
#출력: [0 1 2 3 4 5 6 7 8 9]
a = np.arange(10)
print(a)
#출력 : [-5 -4 -3 -2 -1 0 1 2 3 4]
b= np.arange(-5,5)
print(b)
#출력 :[0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5]
c= np.arange(0,5,0.5)
print(c)
'''-----------------------------------------------
ones, zeros, empty
ones 함수 : 1로만 구성된 넘파이 배열을 생성
-사전에 shape값을 넣어서 원하는 크기의 넘파이 배열 생성
zeros 함수 : 0으로만 구성된 넘파이 배열을 생성
empty 함수 : 활용 가능한 메모리 공간 확보하여 반환
-ones와 zeros는 먼저 shape의 크기만큼 메모리를 할당하고 그곳에 값을 채움
-해당 메모리 공간에 값이 남았을 경우 그 값을 함께 반환
-empty는 메모리 초기화 않아 생성될 때마다 다른 값 반환
생성 시점에서 dtype을 지정해주면 해당 데이터 타입으로 배열 생성
-----------------------------------------------
[실습1]
'''
print(np.ones(shape=(5,2), dtype =np.int8))
print(np.zeros(shape=(2,2), dtype =np.float32))
print(np.empty(shape=(2,4), dtype =np.float32))
'''
ones_like 함수 : 기존 넘파이 배열과 같은 크기로 만들어 내용을 1로 채움
zeros_like : 기존 넘파이 배열과 같은 크기로 만들어 내용을 0로 채움
empty_like : 기존 넘파이 배열과 같은 크기로 만들어 shape크기만큼 메모리를 할당하고 값채움
-----------------------------------------------
[실습]
'''
x = np.arange(12,).reshape(3,-1)
print(x)
print(np.ones_like(x))
print(np.zeros_like(x))
'''
-----------------------------------------------
Identity 함수: 단위행렬(i행렬)을 생성
-매개변수 n으로 n x n 단위 행렬을 생성
'''
print(np.identity(n =3, dtype= int))
print(np.identity(n =4, dtype= int))
'''
-----------------------------------------------
eye 함수: 시작점과 행렬 크기를 지정, 단위행렬 생성
-N은 행의 개수, M은 열의 개수를 지정
-k는 열의 값을 기준으로 시작 인덱스
'''
print(np.eye(N=3,M=5))
#첫번째 행의 3번째자리부터 2로 바꾸고 대각선으로 내려간다
print(np.eye(N=3,M=5,k=2))
'''
-----------------------------------------------
diag 함수 : 행렬의 대각성분 값을 추출
'''
x=np.arange(9).reshape(3,3)
print(np.diag(x))
print(np.diag(x,k=1))
'''
-----------------------------------------------
<통계 분석 함수 >
uniform 함수 : 균등분포 함수
'np.random.uniform(시작값, 끝값,데이터개수)'
'''
#0에서 5사이에 랜덤값을 균등하게 분포하는 10개 값을 가져오기
print(np.random.uniform(0,5,10))
'''
-----------------------------------------------
normal 함수 :정규분포 함수
'np.random.normal(평균값,분산,데이터개수)'
'''
np.random.normal(0,2,10)
print(np.mean(a))
print(np.std(a))
'''
< 넘파이 배열 연산 >
연산 함수: 배열 내부 연산을 지원하는 함수
축 : 배열의 랭크가 증가할 때마다 새로운 축이 추가되어 차원 증가
sum 함수: 각 요소의 합을 반환
'''
test_array = np.arange(1,11)
print(test_array.sum())
'''
SUM 함수를 랭크가 2이상인 배열에 적용할 때 축으로 연산의 방향을 설정
'''
test_array = np.arange(1,13).reshape(3,4)
# Y축을 더해서 계산
print(test_array.sum(axis=0))
# X을 더해서 계산
print(test_array.sum(axis=1))
'''3차원 텐서 연산'''
test_array = np.arange(1,13).reshape(3,4)
third_order_tensor = np.array([test_array,test_array,test_array])
print(third_order_tensor)
'''오른쪽 그림의 각 차원 합계 구현'''
print('Y축 합:',third_order_tensor.sum(axis=0))
print('X축 합:',third_order_tensor.sum(axis=1))
print('행 세트 합:',third_order_tensor.sum(axis=2))
'''
1.test_array, axis=1 축을 기준으로 평균연산 mean
2.test_array 전체 값에 대한 표준편차 연산 (std)
'''
print(test_array.mean(axis=1))
print(test_array.std(axis=0))
'''
sqrt : 제곱근
'''
#각각의 항목에서 제곱근 한다.
print(np.sqrt(test_array))
'''
<연결함수 : 두객체 간의 결합을 지원하는 함수 >
vstack 함수 : 배열을 수직으로 붙여 하나의 행렬을 생성
hstack 함수 : 배열을 수평으로 붙여 하나의 행렬을 생성
넘파이는 열 벡터를 표현할 수 없어 2차원 행렬 형태로 표현
'''
#1행 끼리 붙여서 2차원 행렬로 변경. 수직으로 붙임
v1 = np.array([1,2,3])
v2 = np.array([4,5,6])
print(np.vstack((v1,v2)))
#출력: [[1 2 3]
# [4 5 6]]
'''
실습2 hstack이용 (수평으로 붙여 하나의 행렬 생성)
'''
#출력 : [1 2 3 4 5 6] //1차원
print(np.hstack((v1,v2)))
'''
실습
'''
# 행을 알아서 나누고, 열을 1로
#reshape을 해서 2차원으로 바꾼다. 열이 하나인 2차원 데이터 생성 // 3행 1열
v1 = v1.reshape(-1,1)
v2 = v2.reshape(-1,1)
print('v1',v1)
print('v2',v2)
print('hstack v1,v2 : ',np.hstack((v1,v2)))
#출력:
# hstack v1,v2 : [[1 4]
# [2 5]
# [3 6]]
'''
concatenate 함수 : 축을 고려하여 두개의 배열을 결합
-스택(stack)계열의 함수와 달리 생성될 배열과 소스가 되는 배열의 차원이 같아야함
-두 벡터를 결합하고 싶다면, 해당 벡터를 일단 2차원 배열 꼴로 변환 후 행렬로 나타내야함
예제) v1 = [1,2,3], v2 = [4,5,6] >np,concatenate >
'''
v1 = np.array([1,2,3])
v2 = np.array([4,5,6])
print(np.concatenate((v1,v2)))
#출력 : [1 2 3 4 5 6]
v3 = np.array([1,2,3,4]).reshape(2,2)
v4 = np.array([[5],[6]])
print(np.concatenate((v3,v4), axis=1))
#출력:
# [[1 2 5]
# [3 4 6]]
'''
<사칙연산 함수>
-넘파이는 파이썬과 동일하게 배열 간 사칙연산 지원
--행렬과 행렬, 벡터와 벡터 간 사칙연산 가능
-같은 배열의 구조일때 요소별 연산
--요소별 연산 : 두 배열의 구조가 동일할 경우 같은 인덱스 요소들끼리 연산
실습
'''
x = np.arange(1,7).reshape(2,3)
print(x)
print('x+x',x+x)
print('x-x',x-x)
print('x/x',x/x)
print('x**x',x ** x)