import numpy as np
import matplotlib.pyplot as plt
02wk-2: 파이썬은 좋은 계산기다 (2)
1. 강의영상
2. Imports
3. 2024 수능 – 16,11,8,26,19,12
(풀이1)
= np.linspace(1,3,101)
x = 3**(x-8) # lhs = left hand side 의 약자
lhs = (1/27)**x
rhs '--',label=r"$3^{x-8}$")
plt.plot(x,lhs,'--',label=r"$(\frac{1}{27})^x$")
plt.plot(x,rhs, plt.legend()
대충 \(x=2\) 에서 만나는것 같다. 확인해보자.
3**(2-8), (1/27)**2
(0.0013717421124828531, 0.0013717421124828531)
두 값이 같음. 따라서 \(x=2\)에서 만난다.
(풀이2)
= np.linspace(1,3,101)
x = 3**(x-8) # lhs = left hand side 의 약자
lhs = (1/27)**x
rhs abs(lhs-rhs))] x[np.argmin(np.
2.0
따라서 \(x=2\)에서 만난다.
(풀이1)
= np.linspace(1,15,15)
n = 4
d = d*n-d*7
an an
array([-24., -20., -16., -12., -8., -4., 0., 4., 8., 12., 16.,
20., 24., 28., 32.])
좀 더 보기 편하게 하기 위해서..
=1) np.stack([n,an],axis
array([[ 1., -24.],
[ 2., -20.],
[ 3., -16.],
[ 4., -12.],
[ 5., -8.],
[ 6., -4.],
[ 7., 0.],
[ 8., 4.],
[ 9., 8.],
[ 10., 12.],
[ 11., 16.],
[ 12., 20.],
[ 13., 24.],
[ 14., 28.],
[ 15., 32.]])
\(d\)에 따라 바뀌는 \(\sum_{k=1}^{5}\frac{1}{a_k a_{k+1}}\) 값을 조사하고 이 값이 \(\frac{5}{96}\)이 되는 \(d\)를 찾아보자.
= np.linspace(1,15,15)
n = 4
d = d*n-d*7
an sum(1/(an[:5]*an[1:6])), 5/96 np.
(0.052083333333333336, 0.052083333333333336)
찾아보니까 \(d=4\)이다.
sum(an) np.
60.0
np.stack()
을 이용하는 부분은 너무 내용이 많아 이후에 다시 설명할 예정입니다. 이런것이 가능하다 정도만 알아두시고 이번퀴즈에서 공부하실때는 제외하세요.
(풀이2)
= np.linspace(1,15,15)
n = 4
d = d*n-d*7
an print(f'{np.sum(1/(an[:5]*an[1:6]))-5/96} --> 이 값이 0이 되도록 해야함')
0.0 --> 이 값이 0이 되도록 해야함
구조를 살펴보니까
\[d \to np.sum(1/(an[:5]*an[1:6]))-5/96\]
와 같은 역할을 하는 함수 \(dff(d)\)를 선언하고 \(dff(d)\)가 0이 되는 \(d\)의 값을 찾으면 된다.
def dff(d):
= d*n-d*7
an return np.sum(1/(an[:5]*an[1:6]))-5/96
= np.linspace(3,5,101)
d list(map(dff,d))) plt.plot(
= list(map(dff,d))
dff_vector abs(dff_vector))] d[np.argmin(np.
4.0
따라서 \(d=4\)에서 \(dff(d)=\sum_{k=1}^{5}\frac{1}{a_k a_{k+1}}-\frac{5}{96}=0\)이 만족한다. 따라서 답은
= np.linspace(1,15,15)
n = 4
d = d*n-d*7
an sum(an) np.
60.0
(풀이1)
= lambda x: (3*x**4 -3*x)/(x-1)
f = np.linspace(-2,2,1000)
x '--') plt.plot(x,f(x),
*4 np.mean(f(x))
16.032032032032035
(풀이2)
= lambda x: (3*x**4 -3*x)/(x-1)
f = np.linspace(-2,2,1000)
x '--') plt.plot(x,f(x),
= np.random.rand(1000000)*4 - 2 ## -2~2 까지 임의의수가 골고루 퍼져있음.
x_rand * 4 np.mean(f(x_rand))
16.08910128495068
(풀이3)
= lambda x: (3*x**4 -3*x)/(x-1)
f = np.linspace(-2,2,1000) x
= x[1]-x[0]
delta = f(x)
f_arr = np.cumsum(f_arr) * delta F_arr
=r'$f(x)$')
plt.plot(x,f_arr,label=r'$\int_{-2}^{x}f(x)dx$')
plt.plot(x,F_arr,label plt.legend()
-1] F_arr[
16.048080112143815
(풀이)
= np.linspace(3/4*np.pi, 5/4*np.pi, 101)
x = np.sqrt((1-2*x)*np.cos(x)) y
plt.plot(x,y)
**2) * 2/4*np.pi np.mean(y
7.4555248716100895
2)*np.pi-np.sqrt(2), np.sqrt(2)*np.pi-1, 2*np.sqrt(2)*np.pi-np.sqrt(2), 2*np.sqrt(2)*np.pi-1, 2*np.sqrt(2)*np.pi np.sqrt(
(3.028669375785271,
3.442882938158366,
7.471552313943637,
7.885765876316732,
8.885765876316732)
(풀이)
= np.linspace(1,15,15)
x = lambda x: np.sin(np.pi/4*x)
f = f(2+x)*f(2-x) < 1/4
bool_array bool_array
array([False, True, False, False, False, True, False, False, False,
True, False, False, False, True, False])
# bool_array에서 True에 해당하는 원소들만 출력됨. x[bool_array]
array([ 2., 6., 10., 14.])
sum(x[bool_array]) np.
32.0
(풀이)
= lambda x: 1/9*x*(x-6)*(x-9)
f # note: 함수g는 t에 따라서 달라짐. t->g(x) 를 구현해주는 함수 make_gfunction 을 만들자.
def make_gfunction(t):
def g(x):
if x<t:
return f(x)
else:
return -(x-t)+f(t)
return g
= np.linspace(0,10,1001)
x = 3.2
t = make_gfunction(t)
g = list(map(f,x))
fx = list(map(g,x))
gx =r'$f(x)$',alpha=0.5)
plt.plot(x,fx,label=r'$g(x)$')
plt.plot(x,gx,labelf"t={t}")
plt.title(=-2,ymax=7,color='lime',linestyles='dashed')
plt.vlines(t,ymin plt.legend()
#t -> 주황색곡선의 면적이 계산되는 함수
def cal_area(t):
#t = 3.2
= make_gfunction(t)
g = list(map(f,x))
fx = list(map(g,x))
gx = np.cumsum(gx)*0.01
Gx = np.max(Gx)
S return S
= np.linspace(0,6,101)[1:-1]
t = list(map(cal_area,t))
St =r"$S(t)$")
plt.plot(t,St,labelf'area = {np.max(St):.4f}')
plt.title( plt.legend()
125/4, 127/4, 129/4, 131/4, 133/4
(31.25, 31.75, 32.25, 32.75, 33.25)
4. 자료형과 형변환 – 파이썬 문법
-
파이썬의 기본자료형은 int, float, bool, str, list, tuple, dict, set 등이 있다.
- 0차원 자료형: int, float, bool
- 1차원 자료형: str, list, tuple, dict, set
A. int, float, bool
-
int형
=100 a
type(a)
int
-
float형
=1.2*3
a a
3.5999999999999996
type(a)
float
a?
Type: float String form: 3.5999999999999996 Docstring: Convert a string or number to a floating point number, if possible.
-
bool형
=True ## 숫자1으로 생각할 수 있음
a=False ## 숫자0으로 생각할 수 있음 b
type(a)
bool
type(b)
bool
a?
Type: bool String form: True Docstring: bool(x) -> bool Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.
b?
Type: bool String form: False Docstring: bool(x) -> bool Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.
-
bool형의 연산
=True ## 1
a=False ## 0 b
+b a
1
*b a
0
-
형태변환: float \(\to\) int
(예시1)
=3.0
atype(a)
float
=int(a) a
type(a)
int
(예시2) 이경우는 정보의 손실이 발생
=3.14
aint(a)
3
-
형태변환: int \(\to\) float
=3
atype(a)
int
=float(a)
atype(a)
float
-
형태변환: bool \(\to\) int/float, int/float \(\to\) bool
(예시1)
=True
atype(a)
bool
int(a)
1
float(a)
1.0
(예시2)
=1
abool(a)
True
=0
abool(a)
False
(예시3)
=1.0
abool(a)
True
=0.0
abool(a)
False
B. 1차원 자료의 형태변환
-
list \(\to\) np.array
1,2,3] [
[1, 2, 3]
1,2,3]) np.array([
array([1, 2, 3])
-
np.array \(\to\) list
1,10,10) np.linspace(
array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
list(np.linspace(1,10,10))
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
-
range \(\to\) list, np.array
range(10) # 이게 뭐야??
range(0, 10)
list(range(10)) # 리스트화
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range(10)) # 넘파이배열화 np.array(
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
보충학습: range의 다양한 활용을 익혀보자.
list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list(range(0,10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list(range(3,10))
[3, 4, 5, 6, 7, 8, 9]
list(range(3,10,2))
[3, 5, 7, 9]
-
map 결과물 \(\to\) list
= lambda x: x**2
f list(map(f,[1,2,3])) # [f(1),f(2),f(3)]
[1, 4, 9]
-
map 결과물 \(\to\) np.array로는 불가능
= lambda x: x**2
f map(f,[1,2,3])) np.array(
array(<map object at 0x7f3a09e887f0>, dtype=object)
# 아래는 가능
= lambda x: x**2
f list(map(f,[1,2,3]))) np.array(
array([1, 4, 9])
5. 등차수열을 선언하는 다양한 방법 – 파이썬 문법
아래와 같은 등차수열을 만드는 방법을 살펴보자.
\[1,4,7,\dots,31 \]
1,31,11) np.linspace(
array([ 1., 4., 7., 10., 13., 16., 19., 22., 25., 28., 31.])
list(range(1,32,3))
[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31]
range(1,32,3)) np.array(
array([ 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31])
1,32,3) np.arange(
array([ 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31])
# len(np.arange(1,32,3)) # 원소의 수는 11
= np.arange(1,12)
n 3*n-2
array([ 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31])
= lambda n: 3*n-2
a 1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10),a(11) a(
(1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31)
= np.arange(1,12)
n = lambda n: 3*n-2
a a(n)
array([ 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31])
= np.arange(1,12)
n = lambda n: 3*n-2
a list(map(a,n))
[1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31]
= np.arange(32)
n 1::3] n[
array([ 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31])
6. \(\text{map}(f,{\bf x})\) – 파이썬 문법
-
브로드캐스팅은 매우 편리한 기능임
= lambda x: x+1 f
= np.array([1,2,3])
arr f(arr)
array([2, 3, 4])
-
불가능한 경우도 있음 (1)
= lambda x: np.max(x) - np.min(x) f
= [1,2,3]
x1 = [2,3]
x2 = [3,3,4,5,5,6]
x3 f(x1),f(x2),f(x3)
(2, 1, 3)
list(map(f,[x1,x2,x3]))
[2, 1, 3]
-
불가능한 경우도 있었음 (2)
def dff(d):
= np.linspace(1,15,15)
n = d*n-d*7
an return np.sum(1/(an[:5]*an[1:6]))-5/96
= 1
d dff(d)
0.78125
이게 되는이유?
= 1
d = np.linspace(1,15,15)
n = d*n-d*7
an sum(1/(an[:5]*an[1:6]))-5/96 np.
0.78125
= np.array([1,2,3])
d dff(d)
ValueError: operands could not be broadcast together with shapes (3,) (15,)
이게 안되는 이유?
= np.array([1,2,3])
d = np.linspace(1,15,15)
n = d*n-d*7
an sum(1/(an[:5]*an[1:6]))-5/96 np.
ValueError: operands could not be broadcast together with shapes (3,) (15,)
-
그동안 가능했던 이유
def f(x):
return x+1
=5
x+1 x
6
=np.array([5,6])
x+1 x
array([6, 7])
요약: 어떠한 함수가 원소별로 각각 적용은 가능하지만 한번에 적용 (브로드캐스팅) 은 불가능할때 map은 매우 강력한 도구이다.
7. Bool을 이용한 인덱싱 – 파이썬 문법
-
기본개념
= np.array([1,-2,3,44])
arr True,False,True,True]] arr[[
array([ 1, 3, 44])
-
응용 1 – 양수만 출력
= np.array([1,-2,3,44])
arr >0] arr[arr
array([ 1, 3, 44])
-
응용 2 – 짝수만 출력
= np.array([1,-2,3,44])
arr % 2 == 0] arr[arr
array([-2, 44])
보충학습: 아래의 테크닉도 알아둘것
-
예시1 – 양수를 카운트
= np.array([1,-2,3,44])
arr sum(arr>0)
3
-
예시2 – 짝수를 카운트
= np.array([1,-2,3,44])
arr sum(arr % 2 == 0)
2
8. if문 – 파이썬 문법
-
예시1
def f(x):
if x>0:
return x
else:
return -x
= np.linspace(-10,10,101)
x = np.array(list(map(f,x)))
fx plt.plot(x,fx)
-
예시2
def f(x):
return x if x>0 else -x
= np.linspace(-10,10,101)
x = np.array(list(map(f,x)))
fx plt.plot(x,fx)
-
예시3
= lambda x: x if x>0 else -x f
= np.linspace(-10,10,101)
x = np.array(list(map(f,x)))
fx plt.plot(x,fx)
9. np.random 모듈 – 파이썬 문법
A. np.random.rand()
-
0~1 사이에서 10개의 난수생성
10) np.random.rand(
array([0.43345371, 0.48324862, 0.48046707, 0.41056049, 0.56188841,
0.58762904, 0.6645858 , 0.60568829, 0.83033841, 0.4660302 ])
-
0~2 사이에서 10개의 난수생성
10)*2 np.random.rand(
array([0.44894259, 1.8416822 , 0.50164259, 1.01601855, 0.21073439,
1.8049244 , 0.86548008, 0.38544391, 0.13816874, 1.22858088])
-
1~3 사이에서 10개의 난수생성
10)*2 + 1 np.random.rand(
array([1.58013021, 1.96358901, 2.62137695, 1.74617053, 2.38021729,
1.00043864, 1.42801985, 1.65666288, 2.80405753, 1.23691426])
B. np.random.randn()
-
N(0,1)에서 10개의 난수생성
10) # 표준정규분포에서 10개의 샘플 추출 np.random.randn(
array([-0.88043002, -0.75000612, -0.46393189, 0.73721724, -0.66208613,
0.84740615, -0.31835775, 0.60157946, 0.62744116, 2.06223706])
-
N(1,1)에서 10개 난수생성
10) + 1 np.random.randn(
array([ 1.50801901, 0.06945884, 2.52305677, 0.25080242, -0.25058225,
1.81696343, -0.47341629, 0.51879014, 2.55038708, 0.58788704])
-
N(0,4) 에서 10개 난수생성
10)*2 np.random.randn(
array([-2.26593271, -1.62304968, -1.71372316, 2.93723947, 0.63497107,
2.96605112, 0.71536533, 2.64037886, 0.10782247, -2.97822434])
-
N(3,4) 에서 10개 난수생성
10)*2+3 np.random.randn(
array([ 3.71923104, 1.77496469, 4.04116354, 4.27443252, 2.59130929,
5.48551961, -1.09164073, 3.08090641, 0.88721243, 3.34579357])
C. np.random.randint()
-
[0,7) 에서 10개의 정수생성
0,7,size=10) # [0,7)의 범위에서 10개의 정수 생성 np.random.randint(
array([0, 1, 5, 0, 2, 3, 1, 3, 0, 5])
-
[10,20) 에서 10개의 정수생성
10,20,size=10) # [0,7)의 범위에서 10개의 정수 생성 np.random.randint(
array([11, 10, 10, 19, 13, 11, 11, 11, 15, 19])
D. np.random.choice()
-
[11,22,33] 에서 중복허용하여 20개 추출
11,22,33],20) np.random.choice([
array([33, 33, 11, 33, 11, 11, 33, 22, 11, 33, 33, 33, 22, 33, 11, 11, 22,
22, 33, 22])
-
[11,22,33] 에서 중복허용하여 3개 추출
4)
np.random.seed(11,22,33],3) np.random.choice([
array([33, 33, 22])
5)
np.random.seed(11,22,33],3) np.random.choice([
array([33, 22, 33])
-
[11,22,33] 에서 중복허용하지 않고 3개 추출
11,22,33],3,replace=False) np.random.choice([
array([22, 33, 11])
10. 함수를 리턴하는 함수 – 파이썬 문법
-
예제1: \((P,Q)\)를 입력으로 받아, 기울기가 2이고 점 \((P,Q)\)를 지나는 함수를 리턴하는 함수를 구현하라.
def make_func(p,q):
def func(x):
return 2*(x-p)+q
return func
= np.linspace(-5,5,101)
x = 2,3
p,q = make_func(p,q)
f '--')
plt.plot(x,f(x),'x') plt.plot([p],[q],
-
예제2: \(f(x)=x^2\) 위의 임의의 점을 입력하면 접선을 리턴하는 함수를 구현하라.
def make_func(x0):
= lambda x: x**2
f def func(x):
= 0.0001
h = (f(x0+h)-f(x0))/h
a return a*(x-x0) + f(x0)
return func
= np.linspace(-5,5,101)
x = make_func(1.2)
tan_line **2,'--')
plt.plot(x,x'--') plt.plot(x,tan_line(x),