달나라 노트

Python numpy : sin, cos, tan (삼각함수 값 얻기) 본문

Python/Python numpy

Python numpy : sin, cos, tan (삼각함수 값 얻기)

CosmosProject 2021. 3. 29. 22:34
728x90
반응형

 

 

 

numpy는 삼각함수를 적용한 값을 얻어낼 수 있습니다.

 

import numpy as np


sin_0 = np.sin(np.pi/2 * 0)
print(sin_0)

sin_90 = np.sin(np.pi/2 * 1)
print(sin_90)


-- Result
0.0
1.0

np.sin(x)에서 x는 라디안입니다.

π/2 * 1 = 90도

π/2 * 2 = 180도

π/2 * 3 = 270도

π/2 * 4 = 360도

이런식이죠.

 

sin그래프를 생각하면 위 예시의 값이 왜 0과 1이 나왔는지 아실겁니다.

만약 모르겠다면 아래 예시를 봅시다.

 

 

import numpy as np
import matplotlib.pylab as plt

arr_x_range = np.linspace(0, 2 * np.pi, num=150)
plt.plot(arr_x_range, np.sin(arr_x_range))
plt.xlabel('radian')
plt.ylabel('sin(x)')
plt.show()

matplotlib를 통해서 sin 그래프를 그려봤습니다.

matplotlib.plot(x, y)는 어떻게 쓸수있냐면

y = sin(x)라는 함수를 표현한다고 할 때 첫 번째 argument로 x를, 두 번째 argument로 x에 적용시킬 함수식을 적어줍니다.

 

여기서 x는 내가 원하는대로 넣어줄 수 있는데 보통 ndarray를 전달하며 이 개수가 많으면 많을수록 더 실제 그래프와 근접한 모양을 가져갈 수 있습니다.

 

arr_x_range = np.linspace(0, 2 * np.pi, num=150)

위 코드는 0부터 2π까지의 값을 150개로 나눈 ndarray입니다.

이것은 sin함수를 그릴 때 x값이 될 것입니다.

 

 

 

plt.plot(arr_x_range, np.sin(arr_x_range))

위 내용은 총 150개로 나눠진 x값에 대해 sin함수를 적용하여 y = sin(x)의 y값을 얻어냅니다.

즉 여기서 150개의 x값에 대해 (x, y) 좌표가 형셩됩니다.

 

 

 

plt.xlabel('radian')
plt.ylabel('sin(x)')

x축과 y축의 이름(라벨)을 지정합니다.

 

 

 

 

plt.show()

생성된 150개의 좌표를 찍어서 선으로 이어준 그래프를 보여줍니다.

 

matplotlib에서 그래프를 그리는 원리는 여러 x값에 대해 y값을 계산하여 (x, y) 좌표를 얻고 이 좌표끼리 연결하여 그래프를 그리는 것입니다.

그래서 x값을 더 많이 주면 줄수록 실제 그래프의 모양과 가까워지는것이죠.

 

 

이게 무슨 소린지는 아래의 예시를 통해 더 볼테니 위 예시의 결과를 먼저 봅시다.

 

 

보면 sin 그래프가 그려졌습니다.

sin그래프에서 x축의 대표적인 지점의 y값은 다음과 같습니다.

x = 0 --> y = 0

x = π/2 --> y = 1

x = π/2 * 2 --> y = 0

x = π/2 * 3 --> y = -1

x = π/2 * 4 --> y = 0

 

 

 

 

 

 

import numpy as np
import matplotlib.pylab as plt

arr_x_range = np.linspace(0, 2 * np.pi, num=10)
plt.plot(arr_x_range, np.sin(arr_x_range))
plt.xlabel('radian')
plt.ylabel('sin(x)')
plt.show()

.이번엔 linspace에서 num을 10으로 변경해봅시다.

이렇게되면 0부터 2π까지의 값을 10개로 나눌겁니다.

즉, 그래프를 그릴 때 사용될 (x, y) 좌표가 10개밖에 없는것이죠.

 

따라서 위 그래프를 보면 대충 sin함수같지만 여러 군데 각져있습니다.

그래프를 그리는데 사용된 (x, y) 좌표가 10개밖에 없으니 위처럼 그려지는것이죠.

 

 

 

 

import numpy as np
import matplotlib.pylab as plt

arr_x_range = np.linspace(0, 2 * np.pi, num=200)
plt.plot(arr_x_range, 10 * np.sin(arr_x_range))
plt.xlabel('radian')
plt.ylabel('sin(x)')
plt.show()

만약 plot의 y값에 10을 곱해주면 아래 그림처럼 y = 10 * sin(x)의 그래프를 얻을 수 있습니다.

 

 

 

 

 

 

np.sin 함수의 argument는 단순 어떤 값만 올수 있는 것이 아닙니다.

np.sin(ndarray) 처럼 argument로 ndarray를 넣을 수 있으며 각 ndarray값에 sin 함수를 적용한 값을 ndarray의 형태로 return합니다.

import numpy as np
import matplotlib.pylab as plt

arr_test = np.linspace(0, 2 * np.pi, num=10)
arr_sin = np.sin(arr_test)
print(arr_sin)

plt.plot(arr_test, arr_sin)
plt.show()

 

또한 matplotlib.plot의 인자로서

plot(x값 array, y값 array의 형태로 전달할 수도 있습니다.

 

 

 

 

 

 

삼각함수 하면 진동수를 말하지 않을 수 없죠.

위 내용을 이용해서 x축을 second로 하여 1초에 1번 완료되는 sin함수를 그려봅시다.

 

import numpy as np
import matplotlib.pylab as plt

arr_x = np.linspace(0, 1, num=500) # 1
freq = 1 # 2
plt.plot(arr_x, np.sin((2 * np.pi) * arr_x * freq)) # 3
plt.show()

1. 먼저 0부터 1까지 범위를 500개의 숫자로 나눕시다. 이것은 sin함수의 x값이 될 예정입니다.

 

2. 이건 진동수(frequency)를 의미하는데 우리는 1초에 1번 완료되는 즉, 1초에 1번 진동하는 sin함수를 그릴 것이므로 진동수는 1로 정했습니다.

 

3. 여기가 중요합니다.

sin 함수의 식은 다음과 같습니다.

y = sin(x)

 

 

 

 

 

 

근데 만약 y = sin(2x)를 하면 어떻게될까요?

아래 예시를 봅시다.

import numpy as np
import matplotlib.pylab as plt

arr_x = np.linspace(0, 2 * np.pi, num=500) # 1
plt.plot(arr_x, np.sin(arr_x)) # 2
plt.plot(arr_x, np.sin(2 * arr_x)) # 3
plt.show()

1. 0부터 2π까지의 값을 500개로 나눕니다. 이것은 x값이 될 예정이며 2π로 정한 이유는 sin(x) 함수의 1주기가 0~2π이기 때문입니다.

 

2. y = sin(x)처럼 일반적인 sin그래프를 그렸습니다.

 

3. y = sin(2x)의 그래프를 그렸습니다.

 

여기서 약간 팁을 말하자면 plot을 2번 적용하면 아래 이미지처럼 한 번에 2개의 그래프를 보이게 할 수 있습니다.

plot 1번에 그래프 1개입니다.

 

위 이미지를 보십시오.

파란색은 y = sin(x)이며 노란색 그래프는 y = sin(2x)입니다.

동일한 0~2π 구간 동안 sin(x)는 1번 진동하며 sin(2x)는 2번 진동합니다.

 

이렇게 sin의 x값을 2x로 증가시키면 sin함수의 주기가 짧아집니다.

2x일때는 x일때보다 주기가 반감이 되며 진동수는 2배 늘어납니다.

 

잘 생각해보면 너무나도 당연한게

y = sin(x)에서 1주기 완료를 하려면 x = 2π이어야 합니다. 삼각함수는 x값이 무조건 0에서 2π까지 변하면 한 번의 주기를 완료하게 되는것이죠.

 

근데 y = sin(2x)에서 1주기 완료를 하려면 x = π 이면 됩니다.

즉, y = sin(2x)의 함수에선 x값이 0~π이면 1주기를 완료하게 됩니다.

왜냐면 앞에 상수 2가 붙어있으니 x = 0 ~ π라는 것은 2x = 0 ~ 2π라는 뜻이니까 1주기를 뜻합니다.

 

즉, x는 반밖에 안되는데 x앞 상수 2 때문에 1주기를 완료하게 되는거죠.

그래서 주기가 더 짧아지며 진동수는 늘어나는 겁니다.

 

 

 

 

 

 

자 이제 다시 원래 얘기로 들어와서

 

plt.plot(arr_x, np.sin((2 * np.pi) * arr_x * freq)) # 3

위 식을 수학적으로 고쳐보면

y = sin(2π * 1 * x)입니다.

이걸 좀 더 정리해보면 y = sin(2πx)인 것이죠.

 

그러면 이 함수의 1주기는 x가 몇부터 몇까지 변해야할까요?

 

2πx = 0 ~ 2π  -->  x = 0 ~ 1

위 식으로 보자면 2πx가 0에서 2π까지 변하면1주기이므로

x는 0에서 1까지 변하면 1주기가 된다는 뜻입니다.

x는 second(초)라고 했으므로 결국 1초에 1번 주기를 완료하는(= 1초에 1번 진동하는) 그래프가 완성되는것이죠.

아래 그래프처럼요.

 

 

 

 

 

 

import numpy as np
import matplotlib.pylab as plt

arr_x = np.linspace(0, 1, num=500)
freq = 10
plt.plot(arr_x, np.sin((2 * np.pi) * arr_x * freq))
plt.show()

자 이제 위 코드가 이해되시나요?

이전 예시와 동일하지만 freq = 10으로 셋팅하였습니다.

 

plt.plot(arr_x, np.sin((2 * np.pi) * arr_x * freq))

위 코드를 수학적 함수식으로 바꿔보면

 

y = sin(2π * 10 * x)입니다.

 

여기서 1주기는

2π * 10 * x = 0 ~ 2π이므로

x = 0 ~ 0.1 --> x가 0에서 0.1까지 변하면 1주기를 완료하게 됩니다. (x축의 단위는 초라고 생각하자했으니 0.1초에 1번 진동하는것이죠.)

 

근데 linspace에서 0부터 1까지의 범위를 x값으로 지정했으니

0.1초에 한번씩 1초에는 10번 진동하게 될겁니다.

 

이걸 10Hz라고도 합니다.

(1Hz = 1초에 1번 진동, 60Hz = 1초에 60번 진동)

 

 

 

 

 

 

728x90
반응형
Comments