본문 바로가기

Python

Python - Numpy

### numpy 
### Numerical Python의 약자
### 파이썬에서 수치 해석, 통계 관련 모듈
### 다차원 배열 객체 제공 
import numpy as np

# 배열 생성
# 0~14의 숫자를 3,5행의 2차원 배열로 만든다
a=np.arange(15).reshape(3,5)
print(a)
print(type(a))
print(a.shape) #행과 열 조회 

# 배열의 차수
a.ndim #2차원 배열 
a.dtype #배열의 요소의 자료형 
a.dtype.name #배열의 요소의 자료형의 이름 
a.itemsize #배열의 요소의 크기(byte 단위)
           #int32 자료형은 4바이트값 저장함 
a.size     # a 배열의 요소의 갯수 
a.data     # 실제 저장된 요소의 버퍼

# 배열 생성 
# 리스트 형태의 배열 
b = np.array([6,7,8])

type(b)
b.data

# np.array 함수를 이용한 배열 생성은 리스트나 튜플에서 배열 생성이 가능
# 아래는 에러 발생
c = np.array(6,7,8)

# 배열 생성
d = np.array([(1.5,2,3),(4,5,6)])
d

# d배열의 차원을 출력하기 
d.ndim

# d배열의 요소의 갯수 출력하기
d.size

# 0으로 초기화하여 배열 생성하기 
e = np.zeros((3,4)) #3행 4열 배열 생성하고, 모든 값을 0으로 채움
e

# 모든 값을 1로 초기화하여 배열 생성하기
f= np.ones((3,4))
f

# 0~5까지의 값을 가진 일차원 배열을 생성하기
g = np.arange(6)
g

# 0 ~ 9999까지 값을 가진 일차원 배열 생성하기
h = np.arange(10000)
h

# 0 ~ 9999까지 값을 가진 10x10 배열 생성하기
i = np.arange(10000).reshape(100,100)
i

# 0부터 2까지의 9개로 균등 분할한 수의 배열 
j = np.linspace(0,2,9)
j

np.pi #원주율 
# 0부터 원주율까지의 수를 균등 분할하여 10개를 가져오자 
k = np.linspace(0,np.pi,9)
k

# 0부터 원주율 * 2 까지의 수를 균등하게 분할해서 100를 배열로 생성 
l = np.linspace(0,np.pi*2,9)
l

# np.sin : sin 삼각함수의 값 
m = np.sin(l)
m

# m = np.sin(np.pi/2) = 90도(1) / degree : 90도
m = np.sin(np.pi/2) #sin(90) = 1 
m

##### numpy 연산
a = np.array([20,30,40,50])
b = np.arange(4) #0,1,2,3
c = a-b # 배열 - 배열 : 각각의 요소들이 연산 
c
c = b**2 # 배열 ** 상수값 : 배열의 요소들의 연산 
c
c = a < 35 # a 배열의 요소들의 비교를 해서 참, 거짓인 배열로 생성 
c
type(c)


##### 2차원 배열의 연산
a = np.array([[1,1],[0,1]])
b = np.array([[2,0],[3,4]])
print(a)
print(b)
a * b #각 위치 요소들간의 곱 
a @ b #행렬의 곱 / 파이썬 3.5 이상
a.dot(b) #행렬의 곱

## 난수 생성하기
rg = np.random.default_rng(1) # 난수 생성기 
rg 

# 2행3열의 배열 자료형 정수형
a = np.ones((2,3),dtype=int)
a

# 실수형
b = rg.random((2,3))
b

# 에러 없음
a *3.5
a

# a배열의 요소들의 값을 *3을 한 값을 다시 a배열로 대입
a *= 3 
a

#a배열의 요소는 정수만 가능 
a *= 3.5 
a

b += a 
b

c = np.arange(6).reshape(2,3)
c

a += c
a

#
a = np.ones(3,dtype=np.int32) #정수형
b = np.linspace(0,np.pi,3) #실수형
c = a+b #실수형
c.dtype #실수형. 정수 + 실수 

#
rg = np.random.default_rng(1)
a = rg.random((2,3))
a

# 합계
print("a 배열의 합 : ", a.sum())
print("a 배열의 최소값 : ", a.min())
print("a 배열의 최대값 : ", a.max())

 

# 버젼
print(np.__version__)

# 크기가 10이면서 내용이 0인 벡터 a를 생성하기
a = np.zeros(10)
print(a)

# 크기가 10이면서 내용이 1인 벡터 b를 생성하기
b = np.ones(10)
print(b)

# a 벡터의 메모리 크기 출력하기. 한 개의 요소 바이트수 * 요소의 갯수
# 한개의 요소 바이트 수
a.itemsize

# 요소의 갯수
a.size

# a 벡터의 메모리 크기
a.itemsize * a.size

# a 벡터의 5번째 값이 1인 벡터를 생성하기
a[4] = 1
print(a)

# 10부터 49까지의 값을 가지는 벡터 c 생성하기
c = np.arange(10,50)
print(c)

# c 벡터의 최대 최소 합계 출력하기
c.max()
c.min()
c.sum()
c.mean()

# 0부터 8까지의 값을 3행 3열 행렬로 생성하기
d = np.arange(0,9).reshape(3,3)
print(d)
d = np.arange(9).reshape(3,3)
print(d)

e = np.arange(12).reshape(3,4)


# e 행렬의 합계 구하기
e.sum()

# e 행렬의 행의 합계 구하기
e.sum(axis=1)

# e 행렬의 열의 합계 구하기
e.sum(axis=0)

# e 행렬의 행의 최대값 구하기
e.max(axis=1)

# e 행렬의 열 중 최대값 구하기
e.max(axis=0)

# e 행렬의 행 중 최소값 구하기
e.min(axis=1)

# e 행렬의 열 중 최소값 구하기
e.min(axis=0)

# e 행렬의 최대값, 최소값 구하기
e.max(),e.min()

# cumsum : 행의 누적값
e.cumsum(axis=1)

# cumsum : 열의 누적값
e.cumsum(axis=0)


f = np.arange(10)**3


# 3번째 요소
f[2]

# 3번째 5번째 요소 출력하기 2~4번 인덱스 
f[2:5]

# 0번 인덱스부터 5번 인덱스까지를 한칸 건너서 요소의 값을 1000 대입
f[:6:2]=1000
f

# f 배열의 값을 역순으로 출력하기
f[::-1]

# 반복문에서 사용 가능 
for i in f : 
    print(i**(1/3.))

# 요소가 0과 1로 이루어진 10행 10열 배열 생성하기

# 1
a = np.zeros((10,10))
print(a)

a[0] = 1
a[9] = 1
a[:,0:1] = 1
a[:,9:] = 1
print(a)


# 2
a = np.ones((10,10))
a[1:9,1:9] = 0 
a

# 3
a = np.ones((10,10))
a[1:-1,1:-1] = 0
a

# pad 함수를 이용하기. 행과 열을 추가하기 
a = np.zeros((8,8))
a = np.pad(a, pad_width=1,constant_values=1)
a

# 함수를 이용해서 요소들의 값을 설정하기
# fromfunction(함수,(행,열),타입)
def f(x,y) :
    return 10 * x + y

b = np.fromfunction(f,(5,4),dtype=int)
b

# b 배열의 21 값을 출력하기 
b[2,1]

# b 배열의 1열의 값들을 출력하기
b[0:5,1:2]
b[0:5,1]
b[:,1]

# b 배열의 1행의 값들을 출력하기
b[1]

# b 배열의 1행~2행의 값들을 출력하기
b[1:3]
b[1:3,]
b[1:3,:]

# b 배열의 마지막 행의 값들을 출력하기 
b[-1]

# b 배열의 마지막 열의 값들을 출력하기
b[:,-1]

# 반복문 2차원 배열의 각 행을 출력하기
for row in b:
    print(row)

# 요소들만 출력하기 
for row in b:
    for e in row :
        print(e)

# b.flat : 배열의 요소들만 리턴, 반복문에서 사용 가능
print(b.flat)
for e in b.flat:
    print(e)


# np.random.random((3,4)) : 1 미만의 난수 실수를 3행 4열 배열 생성
# 난수를 이용한 배열 생성

a = np.random.random((3,4))
a

# 난수를 이용한 배열 생성 0~9 사이의 난수만 저장
# 0 <= x(요소값) < 1.0 : 1미만
# 0 <= x * 10 <1.0 : 10미만
# np.floor : 작은 근사 정수 
b = np.floor(10*np.random.random((3,4)))
b

# 난수를 이용한 배열 생성. 1~10 사이의 난수만 저장
c = np.floor(10*np.random.random((3,4))) + 1
c

# np.ceil 큰 근사 정수
c = np.ceil(10*np.random.random((3,4))) 
c

# 모든 배열을 1차원 배열로 변경
a.ravel()
a # 변경 적용 안됨

# 3행 4열 배열을 6행 2열로 변경
a.reshape(6,2)
a # 변경 적용 안됨 

# 3행 4열 배열을 전치 행렬
a.T # a배열 자체의 변경 X 결과만 리턴
a # 변경 적용 안됨

# a 전치행열의 행과 열을 출력하기
a.T.shape
a.shape

# resize 함수 : 배열의 형태 변경
a.resize(6,2)
a

# a 배열의 형태를 3행 4열로 변경하기
# -1 값을 행에 맞도록 열을 자체적으로 처리
a.reshape(3,-1)

### 배열 합하기
### a 배열 : 0~9까지의 요소를 가진 2행 2열 배열 생성하기
### b 배열 : 0~9까지의 요소를 가진 2행 2열 배열 생성하기
a = np.floor(10 * np.random.random((2,2)))
b = np.floor(10 * np.random.random((2,2)))
a
b

# a,b 배열을 세로로 붙이기
np.vstack((a,b))

# a,b 배열을 가로로 붙이기
np.hstack((a,b))


from numpy import newaxis

# 결과가 행렬 형태로 
np.column_stack((a,b))

a1 = np.array([4.,2.])
b1 = np.array([3.,8.])
np.column_stack((a1,b1))
np.vstack((a1,b1))
np.hstack((a1,b1))

# newaxis
a[:,newaxis]

# 배열 분리하기 
a = np.floor(10*np.random.random((2,12)))
a
np.hsplit(a,3) #3개의 배열로 분리

# 배열의 복사
# 0~9까지의 난수 10개로 이루어진 배열 생성
a = np.random.randint(10,size=10)
a
a_sub = a[:2] #0,1번 요소
a_sub

a_sub[0] = 20
a_sub

a_sub[5] #오류발생
a[5]

# a 배열의 다른 배열을 생성하기 

a_cop = a.copy() # copy 함수 : 배열을 복사. 다른 객체로 저장됨.
a_cop 

a_cop[0] = 100
a_cop 


b = a
b #같은 영역의 배열 

a[0] = 50
b
a


# a : 3행 4열 1부터 10까지의 난수 값을 배열
a = np.random.randint(10,size=((3,4))) +1
a

# a 행렬의 1열과 2열의 값만 가지는 배열 s를 생성하기
s = a[:,1:3]
s

# s 배열의 모든 값을 100으로 수정
s[:] = 100
s
a # a의 1,2열도 수정된다.

# a 객체를 b 객체에 대입
b = a 
b
a

# a 배열 제거하기
del a 
b #b는 존재
a #a는 제거

### 인덱스 처리
#[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121]
a = np.arange(12)**2
a

i = np.array([1,1,3,8,5]) #배열
i

# a배열중 i배열에 해당하는 요소들만 출력하기
a[i]

j = np.array([[3,4],[9,7]])
j

a[j]
a

# c : 20부터 145까지를 5개로 균등분배하여 배열 생성하기
c = np.linspace(20,145,5)
c

# d : 0부터 19까지 5행 4열의 배열 생성하기
d = np.sin(np.arange(20)).reshape(5,4)
d

# 각 열중에서 최대값을 가진 요소들만 출력하기
# argmax : axis = 0 : 각 열별로 최대값의 인덱스 리턴
ind = d.argmax(axis=0)
ind
d[ind, range(d.shape[1])]
d[ind]
c[ind]

# 각 행중에서 최대값을 가진 요소들만 출력하기
d.max(axis=1)

# 각 행중에서 최대값의 인덱스만 출력하기
ind = d.argmax(axis=1)
ind

# 각 행중에서 최소값의 인덱스만 출력하기
ind = d.argmin(axis=1)
ind

# 형태가 다른 배열의 연결
x = np.array([[1,2,3],[4,5,6]]) #2행 3열
x
y = np.array([[3,2,1],[6,5,4],[3,2,1]]) #3행 3열
y
z = np.array([[7],[10]]) #2행 1열
z

# 행기준 연결 : vstack
# 열기준 연결 : hstack
np.vstack([x,y]) #x,y배열의 열의 값이 같음. 연결 가능 
np.hstack([x,y]) #x,y배열의 행의 값이 같음. 연결 불가능
np.hstack([x,z]) #x,z배열의 행의 값이 같음. 연결 가능 

# 배열 분리
# 0~15까지의 수를 4행 4열로 생성
x = np.arange(16).reshape((4,4))
x

upper,lower=np.vsplit(x,[2])
upper
lower
left,right=np.hsplit(x,[2])
left
right

# 단위 행렬 생성
y = np.eye(10,10)
y

# 0이 아닌 배열의 요소들만 출력하기 
z = [1,2,0,4,0]
ind = np.nonzero(z)
print(ind)

# 정규분포를 가진 난수 발생
# 히스토그램으로 확인하기
import numpy as np
import matplotlib.pyplot as plt
rg = np.random.default_rng(1)
mu, sigma = 2,1
v = rg.normal(mu,sigma,10000) #표준 정규 분포에 맞도록 난수 생성 
len(v)
v.mean()
v.std()
plt.hist(v,bins=50,density=1) #히스토그램 그래프 작성하기 
# bins = 50 : 50개로 분류
# density = True/False : 밀도값, 빈도수
# n : 밀도값
# bins :막대 간격의 값 

(n, bins) = np.histogram(v, bins=50, density=True)
plt.plot(.5*(bins[1:]+bins[:-1]),n) #선 그래프 # 0.5(1/2) 막대그래프의 가운데
print(n)
print(bins)
plt.plot(.5*(bins[1:]+bins[:-1]),n)

 

 

#그래프

import matplotlib.pyplot as plt
import numpy as np
t = np.arange(0.,5.,0.2) #0~5미만까지 0.2간격 숫자 설정
t
plt.figure()
'''
plt.plot(x축값,y축값,옵션,x축값,y축값,옵션,x축값,y축값,옵션)
t,t,'r--' : r(red), -- :점선
t,t**2,'bs' : b(blue), s(square) : 사각형
t,t**3,'g^' : g(green), ^ :선의종류
'''
plt.plot(t, t, 'r--',t, t**2,'bs',t,t**3,'g^')
plt.show()


# 루트 값 구하기
np.sqrt(2)
np.sqrt(4)

# sin 함수 : sin 삼각함수 
np.cos(np.pi)

# 임의의 난수 5개를 선택하기
a = np.random.random(5)


# 0~9까지의 임의의 정수 난수 5개를 선택하기
a = np.random.randint(0,10,5)
a

 

# 평균:1 표준편차:1 임의의난수 : 5개
a = np.random.normal(1,1,5)
a

# 0~5까지의 임의 정수 10개 선택
a = np.random.randint(0,6,10)
a
a = np.random.choice(6,10)
a

# 0~9까지의 임의 정수 5개 선택 (중복불가)
a = np.random.choice(10,5,replace=False)
a

# 1부터 45까지의 중복없이 6개 숫자를 선택
a = np.random.choice(45,6,replace=False)+1
a.sort()
a

# 확률 적용하여 난수 발생
# 0~5까지의 정수 난수를 100개 선택
# p = [확률값, ...]
# p 속성의 갯수와 선택 가능한 값의 갯수가 일치해야함
# p 속성의 값의 합은 1이어야 함 
a = np.random.choice(6,100,p=[0.1,0.2,0.3,0.2,0.1,0.1])
a

import matplotlib.pyplot as plt
import numpy as np
dice = np.random.choice(6,100,p=[0.1,0.2,0.3,0.2,0.1,0.1])
plt.figure()
plt.hist(dice, bins=6)
plt.show()


import matplotlib.pyplot as plt
import numpy as np
dice = np.random.choice(6,100)
plt.figure()
plt.hist(dice,bins=6)
plt.show()


### -np.pi부터 np.pi까지의 수를 100개를 가진 배열 생성
a=np.arange(-np.pi,np.pi,np.pi/100)
a
plt.figure()
plt.plot(a,np.sin(a))
plt.show()


#
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randint(-100,100,1000)
y = np.random.randint(-100,100,1000)
#abs(x) : 절대값
mask1 = abs(x) > 50 # 절대값이 50 이상인 정보들은 True
mask2 = abs(y) > 50
x = x[mask1 + mask2] # OR mask1 또는 mask2가 하나라도 참인 경우 
y = y[mask1 + mask2] 
print(len(x))
# s = 1000 : 점의 크기 지정
# c = x : 색상 지정 
# cmap = 'jet' : 색의 목록 지정 
plt.scatter(x,y,s=1000,c=x,cmap='jet',alpha=0.7)
plt.colorbar()
plt.show()