그동안 Python NumPy의 단일 배열 unary ufuncs 에 대해서 알아보았습니다.

(http://rfriend.tistory.com/300, http://rfriend.tistory.com/301)

 

이번 포스팅에서는 그동안 배웠던 unary ufuncs 들을 요리조리 조합하고 응용하는 한가지 예를 들어보겠습니다.

 

- 절대값을 구하는 함수 np.abs(x)

- 배열 원소의 부호를 판별하는 np.sign(x) 함수

- 배열의 1개 이상의 원소가 참(True) 인지 평가하는 np.any(x) 함수

 

를 이용해서 특이값, 이상치(outlier)를 탐색하고, indexing해서 다른 값으로 대체하는 방법을 소개하겠습니다.

 

 

먼저 numpy, pandas, matplotlib.pyplot 모듈을 불러오고, 평균이 0, 표준편차가 1인 정규분포로 부터 난수 10,000만개를 생성해보겠습니다.

 

 

In [1]: import numpy as np

   ...: import pandas as pd

   ...: import matplotlib.pyplot as plt

   ...:


In [2]: np.set_printoptions(precision=2)

   ...:

   ...: # setting random seed number

   ...: np.random.seed(10)

   ...:

   ...: # random number 10000 ~ N(0, 1)

   ...: mu, sigma = 0, 1

   ...: x = pd.DataFrame(mu + sigma*np.random.randn(10000))

 

 

 

 

다음으로 dexcribe() 메서드를 사용해서 x의 기술통계량을 알아보고, 히스토그램으로 분포를 살펴보겠습니다. min과 max 값을 보면 평균 0을 중심으로 해서 -3 (-3 sigma)과 +3 (+3 sigma)을 벗어나는 관측치가 있음을 알 수 있습니다.

 

 

# checking descriptive statistics and histogram

In [3]: x.describe()

Out[3]:

0

count 10000.000000

mean 0.005102

std 0.989713

min -3.621639

25% -0.652208

50% 0.013111

75% 0.675040

max 3.691489


In [4]: plt.hist(x)

Out[4]:

(array([ 15., 139., 583., 1626., 2733., 2679., 1606., 497.,

107., 15.]),

array([-3.62, -2.89, -2.16, ..., 2.23, 2.96, 3.69]),

<a list of 10 Patch objects>)

 

 

 

 

 

정규분포를 띠는 데이터셋의 경우 평균으로 부터 +3 sigma, -3 sigma 를 벗어나는 데이터의 경우 전체 데이터셋 중 99%가 존재하는 구간을 벗어나는 특이값, 이상값(outlier)로 간주할 수 있습니다.

 

이번 예제에서 x는 평균이 '0'이고 표준편차가 '1'인 정규분포를 따르므로, np.abs(x)와 any(1) 함수를 조합해서 사용하면 1만개의 관측치를 가지는 x로부터 +- 3 sigma를 벗어나는 특이값만 쏙 빼올 수 있습니다.  count() 메소드로 특이값 개수도 세볼 수 있구요.

 

 

# indexing outlier rows over mu + 3sigma, less mu - 3 sigma

In [5]: x[(np.abs(x) > 3).any(1)]

   ...:

Out[5]:

0

412 -3.204401

1036 -3.317669

1558 -3.112645

2190 3.609161

3948 3.454845

4912 -3.372347

5016 -3.393109

5158 3.193371

5618 3.177053

5750 3.158873

6135 3.077068

6303 3.142285

6689 -3.621639

6760 3.027240

6986 -3.303552

7353 -3.214030

7892 3.561219

8281 3.691489

9179 3.286370

9335 3.503309

 

# counting the number of outliers

In [6]: x[(np.abs(x) > 3).any(1)].count()

Out[6]:

0 20

dtype: int64

 

 

 

 

이번에는 np.sign(x) 함수를 곁들여 사용하여 +- 3 sigma를 벗어나는 관측치값을 모두 +-3 으로 대체해보겠습니다. (즉, +3 sigma보다 큰 특이값은 +3으로 대체, -3 sigma 보다 작은 특이값은 -3으로 대체) 

 

x.describe()로 요약통계량을 살펴보니 min -3, max 3으로 바뀌었지요? 히스토그램도 -3 ~ +3 까지 분포로 바뀌었구요.

 

 

In [7]: x[np.abs(x) > 3] = np.sign(x)*3


In [8]: x[(np.abs(x) >= 3).any(1)]

Out[8]:

0

412 -3.0

1036 -3.0

1558 -3.0

2190 3.0

3948 3.0

4912 -3.0

5016 -3.0

5158 3.0

5618 3.0

5750 3.0

6135 3.0

6303 3.0

6689 -3.0

6760 3.0

6986 -3.0

7353 -3.0

7892 3.0

8281 3.0

9179 3.0

9335 3.0


In [9]: x.describe()

Out[9]:

0

count 10000.000000

mean 0.004968

std 0.987624

min -3.000000

25% -0.652208

50% 0.013111

75% 0.675040

max 3.000000


In [10]: plt.hist(x)

Out[10]:

(array([ 76., 292., 755., 1554., 2269., 2299., 1648., 762.,

277., 68.]),

array([-3. , -2.4, -1.8, ..., 1.8, 2.4, 3. ]),

<a list of 10 Patch objects>)

 

 

 

통계 분포 방법 외에 특이값 찾는 방법이 서너가지 더 있는데요, 그건 다음번에 기회 될 때 별도로 포스팅을 하겠습니다. (언제가 될지는 기약 못하겠네요. ^^;)

 

많은 도움 되었기를 바랍니다.

 

728x90
반응형
Posted by Rfriend
,

이전 포스팅에서는
 
 - 범용함수(universal function, ufuncs)의 정의 및 유형
 
 
(1) 1개의 배열에 대한 ufuncs (Unary universal functions) 중에서
 
 - (1-1) 올림 및 내림 범용 함수 (rounding ufuncs)
 - (1-2) 합(sums), 곱(products), 차분(difference), 기울기(gradient) 범용함수
 - (1-3) 지수함수(exponential function), 로그함수 (logarithmic function)

 - (1-4) 삼각함수(trigonometric functions) 

 - (1-5) 절대값(absolute), 제곱근(square root), 제곱값(square), 정수와 소수점 값 분리(integral and fractional parts), 부호(sign) 판별 함수

 

등에 대해서 알아보겠습니다.

 

 

이번 포스팅에서는 (1-6) 1개 배열 대상의 논리 범용 함수(Logic Unary ufuncs) 에 대해서 알아보겠습니다. 논리 함수(logic functions)는 참(True) 또는 거짓(False)의 boolean 값을 반환합니다.

 

 

 

 

 

  (1-6-1) 배열의 원소에 대한 논리 함수 (logic functions for array contents)

 

  (1-6-1-1) 배열에 NaN(Not a Number) 포함 여부 확인 함수 : np.isnan(x)

 

 

# isnan : Test element-wise for NaN(Not a Number) and return result as a boolean array

 

In [1]: import numpy as np


In [2]: a = np.array([0, 1, 2, np.nan, 4, np.inf, np.NINF, np.PINF])


In [3]: a

Out[3]: array([ 0., 1., 2., nan, 4., inf, -inf, inf])


In [4]: np.isnan(a)

Out[4]: array([False, False, False, True, False, False, False, False], dtype=bool)

 

 

 

 

  (1-6-1-2) 배열에 유한수(finite number) 포함 여부 확인 함수 : np.isfinite(x)

 

 

# isfinite : Test element-wise for finiteness (not infinity or not Not a Number)

 

In [5]: a

Out[5]: array([ 0., 1., 2., nan, 4., inf, -inf, inf])


In [6]: np.isfinite(a)

Out[6]: array([ True, True, True, False, True, False, False, False], dtype=bool)

 

 

 

 

 (1-6-1-3) 배열에 무한수(infinite number) 포함 여부 확인 함수 : np.isinf(x)

 

 

# isinf : Test element-wise for positive or negative infinity

 

In [7]: a

Out[7]: array([ 0., 1., 2., nan, 4., inf, -inf, inf])

 

In [8]: np.isinf(a)

Out[8]: array([False, False, False, False, False, True, True, True], dtype=bool)

 

 

 

 

  (1-6-1-4) 배열에 음의 무한수 포함 여부 : np.isneginf(x)

 

 

# isneginf : Test element-wise for negative infinity, return result as bool array

 

In [9]: a

Out[9]: array([ 0., 1., 2., nan, 4., inf, -inf, inf])

 

In [10]: np.isneginf(a)

Out[10]: array([False, False, False, False, False, False, True, False], dtype=bool)

 

 

 

 

  (1-6-1-5) 배열에 양의 무한수 포함 여부 확인 함수 : np.isposinf(x)

 

 

# isposinf : Test element-wise for positive infinity, return result as bool arry

 

In [11]: a

Out[11]: array([ 0., 1., 2., nan, 4., inf, -inf, inf])

 

In [12]: np.isposinf(a)

Out[12]: array([False, False, False, False, False, True, False, True], dtype=bool)

 

 

 

 

  (1-6-2) 참 확인 논리 함수 (Logic functions for truth value testing)

 

  (1-6-2-1) 배열의 모든 원소가 참(True) 인지 평가하는 함수 : np.all()

 

축(no axis, axis=0, axis=1) 에 따라서 어떻게 참(True) 여부를 평가하는지 유심히 보시기 바랍니다.

 

 

# np.all() : Test whether all array elements along a given axis evaluate to True

 

In [13]: np.all([[True,False],[True,True]])

Out[13]: False


In [14]: np.all([[True,False],[True,True]], axis=0)

Out[14]: array([ True, False], dtype=bool)

 

In [15]: np.all([[True,False],[True,True]], axis=1)

Out[15]: array([False, True], dtype=bool)

 

 

 

 

  (1-6-2-2) 배열의 1개 이상의 원소가 참(True) 인지 평가하는 함수 : np.any()

 

 

# np.any() : Test whether any array elements along a given axis evaluate to True

 

In [16]: np.any([[True,False],[True,True]])

Out[16]: True


In [17]: np.any([[True,False],[True,True]], axis=0)

Out[17]: array([ True, True], dtype=bool)


In [18]: np.any([[True,False],[True,True]], axis=1)

Out[18]: array([ True, True], dtype=bool)

 


 

In [21]: np.any([[False,False],[True,True]], axis=0)

Out[21]: array([ True, True], dtype=bool)

 

In [22]: np.any([[False,False],[True,True]], axis=1)

Out[22]: array([False, True], dtype=bool)

 

 

 

 

  (1-6-3) 단일 배열 원소에 대한 논리 연산(Logical operations)을 위한 논리 함수

 

  (1-6-3-1) 배열 원소가 조건을 만족하지 않는 경우 참 반환 : np.logical_not(condition)

 

 

# logical_not : Compute the truth value of NOT x element-wise, equivalent to -x

 

In [23]: b = np.array([0, 1, 2, 3, 4])


In [24]: np.logical_not( b <= 2 )

Out[24]: array([False, False, False, True, True], dtype=bool)

 

 

 

2개 배열 간 함수인 Binary Universal Unfctions(Ufuncs) 소개는 http://rfriend.tistory.com/286 를 참고하시기 바랍니다.

 

많은 도움 되었기를 바랍니다.

 

 

 

728x90
반응형
Posted by Rfriend
,

이전 포스팅에서는
 
 - 범용함수(universal function, ufuncs)의 정의 및 유형
 
 
(1) 1개의 배열에 대한 ufuncs (Unary universal functions) 중에서
 
 - (1-1) 올림 및 내림 범용 함수 (rounding ufuncs)
 - (1-2) 합(sums), 곱(products), 차분(difference), 기울기(gradient) 범용함수
 - (1-3) 지수함수(exponential function), 로그함수 (logarithmic function)

 - (1-4) 삼각함수(trigonometric functions)

 

들에 대해서 알아보았습니다.

 

이번 포스팅에서는 Unary ufuncs 중에서 

 

 - (1-5) 수 처리 함수, 부호 판별 범용 함수들로서

 

수 처리 함수 : 절대값(absolute value), 제곱근(square root), 제곱값(square), 정수와 소수점 값(integral and fractional parts)

 

부호(sign) 판별 함수 : 1 (positive), 0(zero), -1(negative) 값 반환

 

등에 대해서 알아보겠습니다.

 

 

먼저, 수 처리 관련된 Unary funcs 입니다.  절대값, 제곱근, 제곱, 정수와 소수점 값 등 기본적인 것들로서 예제를 보면 금방 이해할 수 있기 때문에 추가적인 설명은 안 달겠습니다.

 

  (1-5-1) 배열 원소의 절대값 (absolute value) 범용 함수 : np.abs(x), np.fabs(x)

 

 

In [1]: import numpy as np


In [2]: x = np.array([-100, 1, -4, 100])


In [3]: x

Out[3]: array([-100, 1, -4, 100])

 

# abs, fabs : element-wise absolute value for integer, floating point, complex values

 

In [4]: np.abs(x)

Out[4]: array([100, 1, 4, 100])

 

In [5]: np.fabs(x)  # faster abs for non-complex-valued data

Out[5]: array([ 100., 1., 4., 100.])

 

 

 

 

  (1-5-2) 배열 원소의 제곱근(Square Root) 범용 함수 : np.sqrt(y)

 

 

In [6]: y = np.array([1, 4, 100])

 

# sqrt : Compute the square root of each element, equivalent to x**0.5

In [7]: np.sqrt(y)  # equivalent to x**0.5

Out[7]: array([ 1., 2., 10.])

 

In [8]: y**0.5

Out[8]: array([ 1., 2., 10.])

 

 

 

 

  (1-5-3) 배열 원소의 제곱값 (square value) 범용 함수 : np.square(y)

 

 

In [9]: y

Out[9]: array([ 1, 4, 100])

 

# square : Compute the square of each element, equivalent to x**2

In [10]: np.square(y) # equvalent to y**2

Out[10]: array([ 1, 16, 10000], dtype=int32)

 

In [11]: y**2

Out[11]: array([ 1, 16, 10000])

 

 

 

 

 (1-5-4) 배열 원소의 정수와 소수점을 구분하여 2개의 배열 반환 : np.modf(z)

 

np.modf() 범용함수는 1개의 배열을 input으로 받아서 특이하게도 2개의 배열을 output으로 반환합니다. 반환되는 첫번째 배열은 원래 배열의 각 원소들의 소수점 부분(fractional parts)으로 구성되어 있구요, 반환되는 두번째 배열에는 원래 배열의 각 원소들의 정수 부분(integral parts)으로 구성되어 있습니다.

 

만약 정수 부분으로만 구성된 두번째 배열을 선택하고 싶다면 np.modf(z)[1] 처럼 하면 됩니다.

 

 

In [12]: z = np.array([3.5, 7.8, -10.3])


In [13]: z

Out[13]: array([ 3.5, 7.8, -10.3])

 

# modf : return fractional and integral prats of array as separate array
# 1st array : fractional parts, 2nd array : integral parts

 

In [14]: np.modf(z)

Out[14]: (array([ 0.5, 0.8, -0.3]), array([ 3., 7., -10.]))

 

# indexing 2nd array of the returned array, which are integral parts 

In [15]: np.modf(z)[1]

Out[15]: array([ 3., 7., -10.])

 

In [16]: np.modf(z)[0]

Out[16]: array([ 0.5, 0.8, -0.3])

 

 

 

 

  (1-5-5) 배열 원소의 부호 판별 함수 : np.sign(x)  ☞ 1 (positive), 0(zero), -1(negative)

 

 

# sign : returns the sign of each element : 1 (positive), 0(zero), -1(negative)

 

In [17]: c = np.array([-2, -1, 0, 1, 2])


In [18]: c

Out[18]: array([-2, -1, 0, 1, 2])


In [19]: np.sign(c)

Out[19]: array([-1, -1, 0, 1, 1])

 

 

다음번 포스팅에서는 논리 함수 (logical unary ufuncs)에 대해서 알아보겠습니다.

 

많은 도움 되었기를 바랍니다.

 

728x90
반응형
Posted by Rfriend
,

지난번 포스팅에서는

 

 - Anaconda [Python 3.6 버전] 설치

   (Python 3.6, Spyder, Jupyter Notebook, IPython 설치)

 

 - Python IDE인 Spyder 사용법

 

에 대하여 알아보았습니다.

 

 

이번 포스팅에서는 Python 을 interactive 하게, 편리하게 즉각적으로 결과를 봐가면서 데이터 처리, 분석을 할 수 있는 Jupyter Notebook 사용법을 소개하겠습니다.


특히 실습 교육을 진행할 때, 혹은 데이터 분석 결과를 포함한 내용으로 보고서 작성이나 프리젠테이션 할 때 Jupyter Notebook의 markdown 기능을 곁들여서 코드랑 같이 사용하면 유용하더군요.  Jupyter Notebook 안에 텍스트 뿐만 아니라 이미지 파일이나 심지어 동영상도 삽입해서 수강생들에게 공유할 수 있으니 교육 실습 자료로 Jupyter notebook을 사용하면 여러모로 쓸모가 있습니다. 

 

사용법이 그리 어렵지는 않구요, 시간 좀 들여서 이것 저것 눌러보면서 사용해보면 금방 익힐 수 있을거예요. 다만 처음 사용하는 분 입장에서는 '실행'을 어떻게 하는거지 부터 해서... Rstudio 나 Spyder 와는 UI가 다르기 때문에 낯설은 부분이 있는 만큼, 이번 포스팅은 Jupyter Notebook 첫번째 사용자를 대상으로 포스팅을 써봅니다.

 

 

1. Start 'Jupyter Notebook'


먼저, Windows 사용자라면 아래 화면캡쳐처럼 메뉴바에서 'Anaconda3 > Jupyter Notebook' 메뉴를 선택하면 됩니다. 


 


또는 Anaconda Navigator 를 론칭한 후에, Jupyter Notebook 아이콘을 클릭해서 Jupyter Notebook을 실행할 수도 있습니다. 





혹은 명령 프롬프트 창에서 가상환경 리스트 확인하고, 가상환경 활성화 한 후에 jupyter notebook 을 실행시켜주면 됩니다. (Mac 의 경우 $ source activate base 로 가상환경 활성화 해줌)

-- Windows OS 기준

$ conda info -e  

$ activate base

$ (base) jupyter notebook


 


2. Jupyter Notebook 첫 화면 : (1) Files

 

Jupyter Notebook을 실행 시키면 아래 화면캡쳐와 같이 첫화면이 나타납니다.  특이하게 'Internet explorer' 가 창으로 뜹니다.  (1) Files, (2) Running, (3) Clusters 의 세 개의 tab 으로 구성되어 있습니다.

 

먼저 'Files' tab을 살펴보면 폴더랑 python script 파일 (*.ipynb) 들이 리스트로 줄줄이 나열되어 있습니다.  기존에 저장해두었던 파일 클릭해서 실행시키면 되겠지요?

 

 

 

 

2. Jupyter Notebook 첫 화면 : (2) Running

 

'Running' tab에 들어가 보면 현재 실행 중인 python 파일을 확인할 수 있습니다. 'Shutdown' 단추를 누르면 '죽일 수'도 있구요.

 

 

 

 

2. Jupyter Notebook 첫 화면 : (3) Clusters

 

'Clusters' tab에 가보면 IPython parallel 의 clusters 를 볼 수 있습니다.

 

 

 

2. Jupyter Notebook 첫 화면 : (4) Kernel

 

사용자 웹 UI 화면 말고 뒷단에서는 아래 화면캡처와 같은 Kernel 창이 하나 더 있습니다.  백조의 호수 물 밑의  부지런한 두 물갈퀴 다리 같다고나 할까요.  아래 창은 신경 안쓰셔도 됩니다.

 

 

 

 

3. Jupyter Notebook : Create a new Notwbook with Python 3

 

자, 이제 본론으로 들어가서요, 새로운 Python 3 Notebook 창을 만들어 볼까요?! 

 

우측 상단의 'New' 메뉴를 선택하고 'Python 3'를 클릭해 보세요.

 

 

 

 

4. Jupyter Notebook : Rename Notebook

 

그러면 아래처럼 Notebook 창이 하나 뜹니다.  아래 네모난 빈 Cell에 Python script 쓰면 됩니다. 

파일 제목을 'Untitled'에서 새로운 이름을 부여해서 저장해놓고 시작하는게 좋겠네요.  그쵸?

아래 화면캡쳐의 'Untitled' 부분을 클릭하면 그 아래의 'Rename Notebook' 창이 새로 뜨구요, 새로운 이름을 써 준 후에 'OK' 눌러주면 됩니다.

 

 

 

 

5. Jupyter Notebook : Run current cell (Shift+Enter, Ctrl+Enter)

 

(1) 현재 커서가 있는 Cell 에서 아래 화면캡쳐의 빨강 동그라미 아이콘(▶|)을 클릭하면 Python script가 실행됩니다.

 

(2) 단축키를 쓸 수도 있는데요, 'Shift + Enter' 를 사용하면 현재 커서가 있는 Cell 이 실행이 되고요, 커서가 다음번 Cell로 넘어갑니다.

 

(3) 단축키 중에서 'Ctrl + Enter'를 사용하면 현재 커서가 있는 Cell 이 실행이 되고요, 커서가 현재 Cell에 그래도 남아있게 됩니다.

 

 

 

 

6. Jupyter Notebook : Tool-bar

 

Tool-bar 간단히 살펴보고 가시죠.  순서대로 보면 아래와 같은데요, 두개씩 쌍을 이루고 있습니다.

 

 - 저장 (save)

 

 - 아래에 Cell 추가 (insert cell below)

 - 선택한 Cell 삭제 (cut selected cells)

 

 - 복사 (copy selected cells)

 - 붙여넣기 (paste cells below)

 

 - 선택한 Cell 위로 이동 (move selected cells up)

 - 선택한 Cell 아래로 이동 (move selected cells down)

 

 - 실행 (run cell, select below) <- 'Shift + Enter'

 - 중단 (interupt kernel)

 

 

 

 

7. Jupyter Notebook : Open the command palette

 

아래 화면 캡쳐 상단의 빨간 박스의 아이콘을 클릭하면 --> 그 아래처럼 'palette command' 창이 뜹니다. 'change cell to heading 1', 'change cell to heading 2', .... 처럼 선택할 수 옵션이 여러개 뜨는데요, 위에 있는것일 수록 글자 크기가 큰 부연설명 제목을 달 수 있습니다.

 

 

 

 

8. Jupyter Notebook : (1) Run All, (2) Run All Above, (3) Run All Below

 

Spyder는 Editor 창에 python scripts 를 써놓고 전부 실행, 특정 Cell 실행, 선택한 영역 실행을 하는데 편리합니다.  Jupyter Notebook 에도 이와 비슷한 기능이 있습니다.

 

'Cell' 메뉴를 누르면 '실행(Run)' 관련된 세부 메뉴가 뜨는데요, 이중에서도 'Run All', 'Run All Above', 'Run All Below' 는 Tool-bar에 없는 기능이므로 알아두면 유용할것 같습니다.

 

 

 


9. code 행 번호 표시하기 : Esc + l   (영어 소문자 'l' )


코드가 길면 어느 행인지 찾기가 힘들 수 있는데요, (교육하거나 협업하거나 할 때...) 

이때 코드 행 번호가 옆에 표시 되면 찾아가기에, 의사소통하기에 편할 것입니다. 


[ before ]



[ Esc + l  실행 후 ]  : 왼쪽에 노란색 칠한 부분에 cell 내 행번호가 생성되었음.  토글키로 한번 더 'Esc + l' 누르면 다시 원래대로 돌아감. 



10. Jupyter Notebook 단축키 (shortcuts)


Command mode에서 'H'를 누르면 아래와 같이 2가지 종류(Command mode, Edit mode)의 Jupyter Notebook의 단축키 정보를 확인할 수 있습니다. 


(1) Command mode ('Esc' 를 누르고서...)


저는 Command mode 에서는 마크다운 Esc + M + 1 / 2/ 3, to code 인 Esc + Y 행 삽입 Esc + A, Esc + B, 행 삭제 Esc + D + D 를 많이 쓰는 편입니다. 




(2) Edit mode ('Enter'를 치고서...)


Edit mode 단축키 중에서는 들여쓰기(indentation)를 위해서 Tab, Ctrl-], Ctrl-[, 모두 선택하는 Ctrl-A, 실행 취소하는 Ctrl-Z, 저장하고 체크포인트 하는 Ctrl-S 를 많이 쓰는 편이네요. 




11. Cell 전체에 한꺼번에 코멘트 부호 '#' 넣기 : Ctrl + /


Cell 전체를 블록으로 선택한 후에 Crtl + / 을 누르면 코멘트 부호 '#'가 들어가서 코드가 비활성화되며, 토글키로서 Crtl + / 를 한번 더 누르면 코드가 다시 활성화됩니다. 




12. Python 함수의 옵션, 도움말 살펴보기 : Shift + Tab


위의 10-2에서 소개한 단축키 중에서 또 자주 사용하는 것이 있다면 'Shift-Tab: tooltip' 입니다. 함수의 옵션을 모두 다 정확하게 기억하고 사용하는 것은 현실적으로 어렵습니다. 함수의 옵션과 도움말을 확인하고 참고하고 싶을 때 외부 인터넷 검색하는 것 없이 Jupyter Notebook에서 간단하게 조회할 때 함수에 커서를 위치시켜 놓고 'Shift + Tab'을 누르면 아래와 같이 함수에 대한 사용 설명이 나옵니다. 'Shift + Tab'은 간단한 화면, 'Shift + Tab + Tab'하면 자세한(긴) 설명을 볼 수 있습니다. 




이밖에도 Jupyter Notebook 기능이 여러개 더 있지만 전부 소개하기에는 스크롤 압박이 심하므로 여기까지만 소개하도록 할께요.

 

많은 도움이 되었기를 바랍니다.


이번 포스팅이 도움이 되었다면 아래의 '공감~♡'를 꾸욱 눌러주세요. ^^

 

 

728x90
반응형
Posted by Rfriend
,

지난번 포스팅에서는 Python IDE 인 Anaconda 설치 방법을 알아보았습니다.

 

Anaconda를 설치하면 약 450여 개의 Packages 들과 함께 Spyder, Jupyter Notebook, IPython 등이 자동으로 설치됩니다. 

 

저는 분석 프로그래밍 할 때 수십, 수 백, 수천 줄 코딩해야할 경우가 많으므로 Spyder 편집기를 주로 사용합니다. 그리고 간단한 탐색적 분석할 때 Jupyter Notebook (R, spark 사용 할 때 포함) 을 가끔 사용하구요.

 

처음 Spyder를 사용하는 분이라면 좀 생소할 것이므로 좀더 빨리 사용법을 익힐 수 있도록, 이번 포스팅에서는 제가 유용하게 사용하고 있는 기능 위주로 몇 가지만 추려서 소개하도록 하겠습니다.

 

 

1. Spyder 시작

 

Windows 시작 단추를 누르면 'Anaconda3 (64-bit)' 폴더 아래에 'Spyder' 아이콘을 클릭하면 Spyder 가 시작합니다.

 

 

 

혹은 conda 명령 프롬프트 창에서 

 $ activate base

 $ (base) spyder  

처럼 spyder 를 입력해주면 됩니다. 


Mac 의 경우 명령 프롬프트 창에서 source activate [virtual_envoronment_name] 해주면 됩니다

$ conda info -e

$ source activate base

$ (base) spyder




2. Spyder 창 구성 (windows layout)

 

아래 화면캡쳐한 Spyder 창의 왼쪽은 (1) script Editor 입니다.

오른쪽 상단에는 (2) Variable Explorer, File Exployer, Help tab 이 차례대로 있습니다. 

오른쪽 하단에는 (3) Python console, History log, Ipython console 이 차례대로 있습니다.

 

저는 아래처럼 그냥 Spyder default layout 을 그대로 사용합니다만, 마우스로 특정 창을 drag 해서 원하는 위치에 이동시킬 수 있습니다. 대형 모니터를 사용하는 분이라면 창을 개인취향에 맞게 이리저리 옮기고 크기도 조절해서 사용하시면 됩니다.

 

(1) Editor 창에서 작성한 script는 F9나 ctl+Enter 등을 사용해 명시적으로 실행을 시켜야만 실행이 됩니다. 길게 프로그매링 해야 하고 저장해 두었다가 반복적으로 사용해야 하는 상황이라면 Editor 창에서 script를 작성하고 파일로 저장을 해두어야 겠지요.

 

반면에 (3) Ipython console 에서는 script 작성하고 Enter 를 치면 interactive 하게 실행이 되서 결과를 반환합니다.  간단하게 탐색적 분석하거나 Python 처음에 공부할 때 책보면서 이리저리 연습해보기에 편합니다.

 

[ Spyder default layout ]

 

 

 

 

Spyder는 Rstudio layout 과 동일한 형태의 layout 도 제공한답니다. (View > Windows layout > Rstudio layout 선택)  'File exployer'를 자주 사용하지 않는 사용자라면 Editor 창을 좀 더 넓게 사용할 수 있는 'Spyder default layout'이 좀더 편할거 같습니다.

 

[ Spyder : Rstudio layout ]

 

 

 

 

3. Spyder Outline

 

View > Panes > Outline (Ctrl+Shift+O) 을 선택하면 아래의 두번째 화면캡쳐의 왼쪽 상단에 보이는 것처럼 script 전체의 cell 구분 및 hierarchy 를 한눈에 볼 수 있으며, cell의 제목을 선택하면 해당 cell로 커서가 바로 이동하므로 매우 편리합니다.  대형 화면 모니터를 사용하는 분이라면 매우 유용한 기능 중에 하나입니다.

 

 

 

[ Spyder : Outline (Editor 좌측 상단) ]

 

 

 

 

4. 키보드 단축키 (Keyboard shortcuts)

 

단축키 쓰는거 좋은 하는 분이라면 'Tools > Preferences > Keyboard shortcuts' 를 선택한 후에 default keyboard shortcuts 을 찬찬히 살펴본 후에 '나만의 맞춤형 키보드 단축키'를 설정해보시기 바랍니다.

 

가령, 저는 제일 많이 사용하는 단축키가 'run selection' 의 'F9' (editor 창의 커서가 위치한 script 한 줄 실행, 혹은 블럭으로 선택한 부분의 script 실행) 인거 같네요. 'F9' 말고 다른 단축키로 바꾸러면 더블 클릭해서 활성화 시킨 후에 다른 단축키를 설정해주면 됩니다.

 

 

 

 

5. Spyder : 편집 화면 Syntax 색깔 지정 (Syntax coloring )

 

기본 편집 화면 Syntax 색깔이 마음에 들지 않는다면 'Tools > Preferences > Syntax coloring' 에서 마음에 드는 Systax coloring 을 골라보세요. 가령, 배경이 어둡고 Syntax를 환하게 하고 싶다거나 할 때요.

 

 

 

 

6. Spyder : 실행 (Run)

 

코딩한 script 를 실행할 때 R 사용자라면 'Ctrl+Enter' 단축키를 사용했을 텐데요, Python Spyder 는 4가지(!!!)나 제공하며, 'Ctrl+Enter' 가 있기는 한데 R과는 조금 다릅니다. (Spyder 사용 초창기에 당황했던 기억이...)

 

1) 저장한 파일 전체를 처음부터 끝까지 한꺼번에 실행 (Run file) : F5

2) 현재 커서가 위치한 cell 전체를 실행 (Run current cell) 후 커서 현 cell에 위치 : Ctrl + Enter

   : 여기서 cell 은 '#%%' 로 구분이 된, 위/아래로 '선(line)'으로 구분이 된 덩어리를 말합니다.

3) 현재 커서가 위치한 cell 전체를 실행 후 다음번 cell로 커서 이동 (Run current cell and go to the next one) : Shift + Enter

4) 현재 커서가 위치한 행(row) 또는 선택한 행 전체를 실행 (Run selection) : F9

 

저는 주로 'F9'를 사용하고, 가끔 'Ctrl+Enter' 나 'Shift+Enter' 를 사용합니다.  아주 가끔 'F5'를 사용하구요. 

 

[ Spyder : 실행 (run) ]

 

 

 

 

[ Spyder : Cell (#%% 사용해서 cell 구분) ]

 

 

 

Spyder 우측 상단의 '폴더' 모양 아이콘을 누르고 탐색기로 경로를 설정해주면 'Working directory setting' 이 됩니다.  이거 설정해주면 파일 저장이나 불러오기 할 때 편러합니다.

 

 

 

7. 부가설명 달기 : #

 

만약 여러개의 줄에 한꺼번에 코멘트 기호 '#'을 붙이고 싶다면 먼저 마우스로 '#'을 붙이고 싶은 여러개의 줄을 블록으로 선택한 후에 'ctrl+1' (Mac OS의 경우 'command+1') 을 눌러주면 됩니다.  반대로 여러개의 줄에 '#' 기호가 붙어 있는 것을 해제하고 싶다면 역시 마우스로 블럭 설정한 후에 똑같이 'ctrl+1' (맥북은 'command+1')을 눌러주면 됩니다. 토글키인데요, 은근히 유용합니다. 


 

8. 들여쓰기 (indentation) : 4 spaces (or 8 spaces)

 

'#' 부호를 쓰면 Python script 에 아무런 영향을 주지 않은 상태에서 부가설명을 달 수 있습니다. (R과 동일)  특히 협업을 하면서 Python script를 짜는 경우라면 부가설명을 충실하게 달아주는 것이 여러모로 좋겠지요?!

 

Python은 code block, 함수 정의나 flow control 등을 하는데 있어서 다른 프로그래밍 언어처럼 '{ }'을 사용하지 않구요, 특이하게도 space 로 들여쓰기(indentation)를 해서 구분을 해줍니다.  이게 처음에 적응이 잘 안되고, 참 이상하고, '{ }' 구분없이 어떻게 프로그래밍을 짜서 당황스럽고, 의문이 가고, 대략 난감한데요... 쓰다보면 이게 참 편하구나 하고 적응이 되는 때가 옵니다. 보통은 4 spaces 로 들여쓰기를 하구요, 프로그래머들 중에는 tab 이나 8 spaces 로 들여쓰기(indentation)를 하기도 하는데요, Spyder의 디폴트 들여쓰기가 '4 spaces' 이구요, 저도 '4 spaces' 추천합니다.  사람마다 생각이 다를 수 있겠습니다만은, 저는 Spyder 쓰는 가장 유용한 기능 중의 하나가 자동으로 알아서 '들여쓰기 (indentation)'가 된다는 점, 그리고 'Syntax coloring'이라고 생각합니다.  만약 '들여쓰기'가 잘못되면 에러나므로 조심해야 하고 매우 중요합니다.

 

(참고 : Spyder 메뉴의 Tools > Preferences > Editor > Advanced settings > Indentation characters : 4 spaces  에서 들여쓰기(indentation) 설정 바꿈 가능합니다)

 

 

이밖에도 Spyder에 여러 기능이 많이 있지만, 전부 소개하자니 너무 많기도 하구요, 제가 위에서 소개한 것 외에는 그다지 사용하지 않는 기능들이기도 해서 여기까지만 소개하도록 하겠습니다.

 

 

 

9. Spyder 최신 버전으로 upgrade (update) 하기

 

cmd 창에 conda upgrade spyder 를 입력하면 됩니다.

 

 > conda upgrade spyder

 

 

[ cmd 창에서 conda upgrade spyder 실행 화면 예시 ]

 

 

 


10. 편집 창, Console 창 전부 지우기


 - 사용 중인 객체 전부 지우기 (Clear all objects): (편집창에서) %reset -sf

 - 콘솔 창 전부 지우기 (Clear console window): (편집창 or 콘솔 창에서) %clear (or 콘솔창에 커서 찍고 Ctrl + L )

 


11. 편집창 내 코드 대문자를 소문자로, 소문자를 대문자로 변환하는 단축 키


- 대문자를 소문자로 변환: Ctrl + u

- 소문자를 대문자로 변환: Ctrl + Shift + u 



12. Spyder Window Layout을 Default Layout으로 되돌리기, 현재 Loyout 저장하기


- Default Window Layout으로 되돌리기: View > Window layouts > Spyder Default Layout

- 현재의 Window Layout 저장하기: View > Window layouts > Save current layout




다음번 포스팅에서는 Jupyter Notebook 사용법에 대해서 알아보겠습니다.

 

많은 도움 되었기를 바랍니다.


이번 포스팅이 도움이 되었다면 아래의 '공감~♡'를 꾸욱 눌러주세요. ^^

 

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Python 설치하는 방법을 소개하겠습니다.

 

Python을 설치하고 이용하는 다양한 방법이 있겠습니다만, 이번 포스팅에서는 아래 처럼 제가 사용하는 환경 기준으로만 소개를 해보겠습니다.  

 

제 주위 Python 사용자 중에는 Pycharm 이나 Eclipse 에 설치해서 사용하는거 추천하는 분들도 계시는데요... 저는 Anaconda 설치해서 주로 spyder나 jupyter notebook 사용하곤 하구요, 그동안 별 불편을 못느꼈고 좋습니다.  왠만한 라이브러리도 거의 기본 포함하고 있구요.

 

- IDE : Anaconda (spyder, jupyter notebook, IPython)

- OS : Windows, 64-BIT

- Python version : 3.x (설치 당시의 3.x 최신 버전 사용)

 

 

Python 2.7 버전의 경우 2020년 1월 1일부터 지원이 공식적으로 종료되었습니다. 따라서 Anaconda 배포판으로 Python 설치 시에는 가급적 Python 3.x 의 설치 당시의 Python 최신 버전으로 설치를 하시구요, 가상 환경 (Virtual Envorinment) 에 필요 시 Python 2.7 버전의 가상환경을 추가로 구성하시기 바랍니다. 

(Anaconda 에서 Python 2.7 버전의 가상환경 만들기 참고 : https://rfriend.tistory.com/458)

 

이미 특정 버전의 Python 버전을 사용해서 뭔가를 개발해놓은 상태라서 너무 높은 버전의 Python을 사용하려고 할 때 작동하지 않을 수도 있습니다. Python 버전별 무슨 Package 들을 지원하는 지는 https://docs.continuum.io/anaconda/pkg-docs  에서 확인해 볼 수 있습니다.  

 

서론이 여기까지 하구요, 아래 화면 캡쳐해 놓은대로 따로 해보면서 설치를 해보시지요.  Anaconda installer 다운로드 후에 'Next' 몇번 클릭하다 보면 설치 완료되있을 겁니다. 겁나 쉬워요. (하둡 설치랑은 비교 불가 -_-;)

 

 

1~4. Anaconda installer download

   - (1) 어디서? : https://www.anaconda.com/products/individual

   - (2) OS : Windows  (자기 컴퓨터 맞게 선택할 것)

   - (3) Python 3.x version (최신 버전으로 다운로드)

   - (4) 64-BIT (자기 컴퓨터 맞게 선택할 것)

 


(설치 당시의 최신 Python 3.x 버전 사용하면 됨) 

 

 

 

5. Anaconda installer 더블 클릭하여 시작

 

 

 

 

6. Anaconda installer 계속 'Next' 단추 누르면서 설치 진행

 

 

 

 

7. Anaconda License Agreement : "I Agree"

 

 

 

 

8. Select Installation Type : Just Me (recommended) > Next

 

 

 

 

9. Choose Install Location : 설치 directory 지정 (default 사용) > Next

 

 

 

 

10. Advanced Installation Options : (default 사용)

   - (v) Add Anaconda to my PATH environment variable

   - (v) Register Anaconda as my default Python 3.6

   > Install

 

 

 

 

11. Installation Complete : 설치 진행~ > 완료 후 > Next

 

 

 

 

12. Anaconda 설치 끝 : Finish

 

 

 

 

13. Windows 시작 'Anaconda3'
     > 14.바탕화면에 단축 아이콘 복사하기 (Ctrl + icon drag & drop)

 

 

 

 

 

 

다 끝났습니다.  쉽지요? ^^


혹시 Anaconda 설치가 잘 안되거든 기존 Anaconda를 제어판에서 제거(uninstall)한 후에, 백신 프로그램과 방화벽을 disable 시키고 다시 한번 Anaconda 설치를 해보시기 바랍니다. 


Jupyter Notebook 사용법은 https://rfriend.tistory.com/299 를 참고하세요. 

 

spyder 사용법은 다음 포스팅에서 소개하겠습니다.


많은 도움 되었기를 바랍니다.


이번 포스팅이 도움이 되었다면 아래의 '공감~♡'를 꾸욱 눌러주세요. ^^

 

 

728x90
반응형
Posted by Rfriend
,

이전 포스팅에서는

 

 - 범용함수(universal function, ufuncs)의 정의 및 유형

 

 

(1) 1개의 배열에 대한 ufuncs (Unary universal functions) 중에서

 

 - (1-1) 올림 및 내림 범용 함수 (rounding ufuncs)

 - (1-2) 합(sums), 곱(products), 차분(difference), gradient 범용함수

 - (1-3) 지수함수(exponential function), 로그함수 (logarithmic function)

 

에 대해서 소개하였습니다.

 

이번 포스팅에서는 Unary ufuncs 4번째로

 

 - (1-4) 삼각함수 (trigonometric functions)

 

에 대해서 알아보겠습니다.

 

 

고등학교 때 배웠던 삼각함수 공식을 복습하는 것으로 먼저 시작해보겠습니다. (이미 다 아는 이과생들은 pass... ^^;  긴가민가하는 문과생들은 복기... ^^;;;)

 

sine (줄여서 sin), cosine (줄여서 cos), tangent (줄여서 tan) 공식은 아래 밑변 AC, 높이 BC, 빗변 AB를 가지고 사이각이 (theta degree) 인 직각삼각형 ABC 를 가지고 삼각함수를 나타내본 것입니다.

 

 

 

[ 삼각함수 (Trigonometric Functions) ]

 

 

 

  

삼각함수는 어디에 쓰나 싶을 텐데요, 주기적인 파동형태를 띠는 함수 (예: 주파수, 물결 파동 등) 를 나타낼 때 sine function 을 사용합니다.  벡터 내적 계산할 때 cosine function 을 사용하기도 하구요. 고속 푸리에 변환 (FFT : Fast Fourier Transformation) 과 벡터 내적 계산 관련 자세한 내용은 아래 포스팅 링크 참고하세요.

 

 

 

참고로, degree는 우리가 일반적으로 사용하는 것처럼 원을 0~360도로 표기하는 방법이구요, radian은 부채꼴의 호의 길이와 반지름의 길이가 같게 되는 각도를 1 radian이라고 합니다. 

 

180 degree = π radian 이며,

1 degree = π radian/180 ,

1 radian = 180 degree/ π = 57.3 의 관계가 있습니다. (슬슬 헷갈리기 시작하죠? -_-?)

 

 

Python NumPy의 삼각함수는 radian을 사용하기 때문에 degree 를 radian으로 바꿔주기 위해서 degree * np.py/180 을 해주었습니다. ( np.deg2rad(x) 함수를 사용해도 됨 )

 

 

 

  (1-4-1) 삼각함수 (trigonometric functions) : np.sin(), np.cos(), np.tan()

 

In [1]: import numpy as np


In [2]: np.sin(np.array((0., 30., 45., 60., 90.))*np.pi / 180.)

Out[2]: array([ 0.        ,  0.5       ,  0.70710678,  0.8660254 ,  1.        ])


In [3]: np.cos(np.array((0., 30., 45., 60., 90.))*np.pi / 180.)

Out[3]:

array([  1.00000000e+00,   8.66025404e-01,   7.07106781e-01,
          5.00000000e-01,   6.12323400e-17])


In [4]: np.tan(np.array((0., 30., 45., 60., 90.))*np.pi / 180.)

Out[4]:

array([  0.00000000e+00,   5.77350269e-01,   1.00000000e+00,
          1.73205081e+00,   1.63312394e+16])

 

 

 

 

 

참고로, 아래는 주요 Degree 혹은 radian 별  삼각함수 값 (Special values in trigonometric functions) 들입니다.

 

* 출처 : Wikipedia (https://en.wikipedia.org/wiki/Trigonometric_functions)

 

 

 

 

  (1-4-2) 싸인 곡선 그리기 (plotting sine curve)

 

 

In [5]: import matplotlib.pyplot as plt


In [6]: x = np.arange(0, 2*np.pi, 0.1)


In [7]: y = np.sin(x)


In [8]: plt.plot(x, y)

Out[8]: [<matplotlib.lines.Line2D at 0x94295f8>]

 


In [9]: plt.show()

 

 

 

 

 

주기적으로 회전 운동(a circular movement)을 하는 단자를 시간의 흐름(x축)에 따른 높낮이 변화(y축)를 시계열 그래프로 나타내면 그게 바로 위의 사인 곡선(sine curve)이 됩니다. 저 주기를 가지고 주파수를 계산할 때 FFT (Fast Fourier Transformation)을 사용하구요.

 

 

 

 

 

 

 

  (1-4-3) 삼각함수의 역수

 

삼각함수의 역수cosecant (줄여서 csc), secant (줄여서 sec), cotangent (줄여서 cot) 함수는 아래와 같이 정의합니다.

 

 

 



 

 

 

 

 

 

  (1-4-4) 역삼각함수 : np.arcsin(), np.arccos(), np.arctan

 

 

In [10]: np.arcsin(1) # pi/2

Out[10]: 1.5707963267948966

 

In [11]: np.sin(1.5707963267948966)

Out[11]: 1.0

 

In [12]: np.sin(np.arcsin(1))

Out[12]: 1.0

 


 

In [13]: np.arcsin([-1, 0, 1]) # real part lies in [-pi/2, pi/2]

Out[13]: array([-1.57079633,  0.        ,  1.57079633])


In [14]: np.arccos([-1, 0, 1]) # real part lies in [0, pi]

Out[14]: array([ 3.14159265,  1.57079633,  0.        ])


In [15]: np.arctan([-1, 0, 1]) # real part lies in [-pi/2, pi/2]

Out[15]: array([-0.78539816,  0.        ,  0.78539816])

 

 

 

 

 

  (1-4-5) degree를 radian으로 변환 : np.deg2rad(x)

            radian을 degree로 변환 : np.rad2deg(x)

 

 

degree를 radian으로 바꾸고 싶을 때는 np.deg2rad(x) 함수를 사용하면 되구요,

radian을 degree로 바꾸고 싶을 때는 np.rad2deg(x) 함수를 사용하면 됩니다.

 

 

# Convert angles from degrees to radians : np.deg2rad
# deg2rad(x) is x * pi / 180

 

In [16]: np.deg2rad(180)

Out[16]: 3.1415926535897931

 

 

# Convert angles from radians to degrees : np.rad2deg
# rad2deg(x) is 180 * x / pi

In [17]: np.rad2deg(np.pi)

Out[17]: 180.0

 

 

 

 

많은 도움 되었기를 바랍니다. 

 

 

728x90
반응형
Posted by Rfriend
,

이전 포스팅에서는

 

 - 범용함수(universal function, ufuncs)의 정의 및 유형

 

 

(1) 1개의 배열에 대한 ufuncs (Unary universal functions) 중에서

 

 - (1-1) 올림 및 내림 범용 함수 (rounding ufuncs)

 - (1-2) 합(sums), 곱(products), 차분(difference), 기울기(gradient) 범용함수

 

들에 대해서 알아보았습니다.

 

이번 포스팅에서는 Unary ufuncs 중에서

 

 - (1-3) 지수함수(exponential function), 로그함수 (logarithmic function)

 

에 대해서 알아보겠습니다.

 

 

고등학교 때 지수함수, 로그함수에 대해서 배웠을 텐데요, 기억이 가물가물 하신분들을 위해서 간단히 지수함수, 로그함수에 대해서 먼저 복기를 해본 후에 Python NumPy 의 지수함수, 로그함수 사용법으로 넘어가겠습니다.

 

 

지수함수(exponential function)는 아래 왼쪽의 그래프처럼 인 형태의 함수를 말합니다.  아래 [그림1] 왼쪽의 지수함수 예시 그래프는   지수함수의 그래프로서, (x=0, y=1), (x=1, y=2) 지점을 지나고 있습니다.

 

로그함수(logarithmic function)는 지수함수의 역함수(inverse function) 입니다. 즉, 아래 [그림1] 그래프의 예를 들자면원래 지수함수였던 의 역함수는  함수인데요, 이를 표기하기 편하도록 라고 하자고 약속을 한 것입니다. (밑이 '2'인 로그함수)

 

 

[그림1] 지수함수와 로그함수의 관계 및 그래프 예시

 

 

 

 

특히, 자연상수 e 를 밑으로 하는 로그함수를 자연로그(natural logarithm) 하며, 처럼 쓰기 보다는 보통 자연상수 e를 생략하고 그냥 혹은 로 쓰곤 합니다. 아래 [그림2] 그래프를 참고하세요.

 

(참고로, 자연상수 e2.71828182846... 의 값을 가지는 무리수이며, 수학자의 이름을 따서 '오일러의 수(Euler's number)' 또는 '네이피어의 수(Napier's number)'라고도 함)

 

 

[그림2] 밑(base)이 자연상수 e 인 지수함수와 자연로그 함수 그래프

 

 

 

 

간단한 복기는 여기까지 하고요, 이제 Python NumPy의 지수함수, 로그함수에 대해 알아보겠습니다.

별것 없구요, 간단합니다. ^^'

 

  (1-3-1) 지수함수 (exponential function) : np.exp()

 

NumPy의 np.exp() 함수는 밑(base)이 자연상수 e 인 지수함수  로 변환해줍니다.

 

 

In [1]: import numpy as np


In [2]: x = np.array([0.00001, 1, 2, 4, 10, 100])


In [3]: x

Out[3]:

array([  1.00000000e-05,   1.00000000e+00,   2.00000000e+00,
          4.00000000e+00,   1.00000000e+01,   1.00000000e+02])


In [4]: np.exp(x)

Out[4]:

array([  1.00001000e+00,   2.71828183e+00,   7.38905610e+00,
          5.45981500e+01,   2.20264658e+04,   2.68811714e+43])

 

 

 

 

 (1-3-2) 로그함수 (logarithmic function) : np.log(x), np.log10(x), np.log2(x), log1p(z) 

 

지수함수의 역함수인 로그함수는 밑이 자연상수 e, 혹은 10, 또는 2 이냐에 따라서 np.log(x), np.log10(x), np.log2(x) 를 구분해서 사용합니다.

 

 

# natural logarithm (base e)

 

In [5]: np.log(x)

Out[5]:

array([-11.51292546,   0.        ,   0.69314718,   1.38629436,
           2.30258509,   4.60517019])

 

 

# log base 10

In [6]: np.log10(x)

Out[6]: array([-5.        ,  0.        ,  0.30103   ,  0.60205999,  1.        ,  2.        ])

 

 

# log base 2

In [7]: np.log2(x)

Out[7]:

array([-16.60964047,   0.        ,   1.        ,   2.        ,
           3.32192809,   6.64385619])

 

 

 

 

로그함수의 경우 위의 [그림2]의 하단에 있는 자연로그 함수 그래프를 보면 알겠지만, x=0 인 경우 y가 -무한대(-infinite)의 값을 가집니다.  아래의 Out[9]번에 보면 NumPy 에 '0'이 포함된 배열을 np.log() 함수에 대입하면 'RuntimeWarning: divide by zero encountered in log' 라는 경고메시지가 뜨고, -inf 가 포함된 배열을 반환하게 됩니다. 이럴 때 사용하는 방법이 'x+1'을 해줘서 '0' -> '1' 로 바꿔주는 겁니다. np.log1p() 함수가 바로 이 역할을 해주는 함수입니다. 그러면 y값이 '-inf' -> '0'으로 바뀌게 되죠.

 

 

In [8]: z = np.array([0, 1.71828])


In [9]: np.log(z)

C:\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\start_ipython_kernel.py:1: RuntimeWarning: divide by zero encountered in log

# -*- coding: utf-8 -*-

Out[9]: array([ -inf, 0.54132379])

 

 

# log(1+z) = np.log1p(z)

In [10]: np.log1p(z)

Out[10]: array([ 0. , 0.99999933])

 

 

 

 

물론 np.log1p() 함수를 안쓰고 그냥 np.log() 함수를 써서 아래처럼 np.log(1+z) 라고 해도 똑같은 결과를 얻을 수 있습니다.

 

 

In [11]: np.log(1+z)

Out[11]: array([ 0. , 0.99999933])

 

 

 

 

그럼, 지수함수, 로그함수는 어디에 써먹는 건가 궁금할 것 같습니다.

한가지 예를 들자면 오른쪽으로 심하게 skewed된 멱함수(power law function) 분포를 띠는 데이터를 정규분포(normal distribution) 로 변환할 때 로그 변환 (log transformation)을 사용하곤 합니다.

 

자세한 내용은 오른쪽 포스팅 참고하세요.  ☞  http://rfriend.tistory.com/53

 

 

여기서 끝내기 조금 아쉬우니 지수함수와 로그함수의 성질(properties of exponential and logarithmic function)도 복기해보겠습니다. 논문 읽다보면 지수함수와 로그함수의 성질을 알아야지 이해가 되는 공식 전개가 가끔씩 나오니 기억해두면 좋겠지요?!  증명은 생략합니다. ^^'

 

 

 

다음번 포스팅에서는 Unary ufuncs 의 네번째로 삼각함수(trigonometric functions)를 알아보겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

728x90
반응형
Posted by Rfriend
,

지난번 포스팅에서는 NumPy 에서 제공하는

 

 - (1) 단일 배열 대상의 범용 함수

       (Unary Universal Functions)

 - (2) 2개 배열 대상의 범용 함수

       (Binary Universal Functions)

 

에 대해서 간략히 소개를 하였습니다.

 

그리고 단일 배열 대상의 범용 함수 중에서 (1-1) '올림 혹은 내림 (Rounding)' 함수들(np.around, np.round_, np.rint, np.fix, np.ceil, np.floor, np.trunc)에 대해서 알아보았습니다.

 

이번 포스팅에서는 단일 배열 대상의 범용 함수(Unary ufuncs) 중에서 (1-2) 배열 원소 간 곱(products), 합(sums), 차분(differences) 범용 함수들에 대해서 알아보겠습니다.  (함수가 많아서 한꺼번에 포스팅하기에 버거우므로 여러번 나누어서 포스팅합니다)

 

 

[ Unary ufuncs : 배열 원소 간 곱 (products), 합 (sums), 차분 (differences) ]

 

 

 

 (1-2) 배열 원소 간 곱(products), 합(sums), 차분(differences), 기울기(gradient) 범용함수

 

1차원 배열 b와 2차원 배열 c를 가지고 예를 들어 설명하겠습니다.

 

 In [1]: import numpy as np


In [2]: b = np.array([1, 2, 3, 4]) # 1 dimension


In [3]: b

Out[3]: array([1, 2, 3, 4])


In [4]: c = np.array([[1, 2], [3, 4]]) # 2 dimension


In [5]: c

Out[5]:

array([[1, 2],
        [3, 4]])

 

 

 

 

 (1-2-1) 배열 원소 간 곱 범용 함수 (products universal funcstions) : np.prod()

 

2차원 배열의 경우 axis=0 이면 같은 열(column)위*아래 방향으로 배열 원소 간 곱하며, axis=1 이면 같은 행(row)의 왼쪽*오른쪽 원소 간 곱을 합니다.

 

 

# (1-2-1) np.prod() : Return the product of array elements over a given axis

 

# 1 dimensional array

In [3]: b

Out[3]: array([1, 2, 3, 4])

 

In [6]: np.prod(b)  # 1*2*3*4

Out[6]: 24

 

# 2 dimensional array

In [5]: c

Out[5]:

array([[1, 2],
        [3, 4]])

 

In [7]: np.prod(c, axis=0# [1*3, 2*4]  ↓

Out[7]: array([3, 8])


In [8]: np.prod(c, axis=1# [1*2, 3*4]  →

Out[8]: array([ 2, 12])

 

 

 

 

 (1-2-2) 배열 원소 간 합치기 범용 함수 (sum universal functions) : np.sum()

 

keepdims=True 옵션을 설정하면 1 차원 배열로 배열 원소 간 합을 반환합니다.

 

 

# (1-2-2) np.sum() : Sum of array elements over a given axis

 

# 1 dimensional array

In [3]: b

Out[3]: array([1, 2, 3, 4])

 

In [9]: np.sum(b) # [1+2+3+4]

Out[9]: 10

 

# the axes which are reduced are left in the result as dimensions with size one

In [10]: np.sum(b, keepdims=True)

Out[10]: array([10])  # 1 dimension array

 

In [11]: np.sum(b, keepdims=True).shape  # 1 dimension array

Out[11]: (1,)

 

 

 

2차원 배열의 경우 axis=0 을 설정하면 같은 열(column)의 위+아래 원소 값을 더하며, axis=1 을 설정하면 같은 행(row)의 왼쪽+오른쪽 원소 값을 더하여 1차원 배열을 반환합니다.

 

 

# 2 dimensional array

In [5]: c

Out[5]:

array([[1, 2],
        [3, 4]])

 

In [12]: np.sum(c, axis=0)  # [1+3, 2+4]  ↓

Out[12]: array([4, 6])


In [13]: np.sum(c, axis=1)  # [1+2, 3+4]  →

Out[13]: array([3, 7])

 

 

 

 

 (1-2-3) NaN 이 포함된 배열 원소 간 곱하기 범용 함수 : np.nanprod()

 

np.nanprod() 함수는 NaN (Not a Numbers) 을 '1'(one)로 간주하고 배열 원소 간 곱을 합니다.

 

 

# (1-2-3) np.nanprod() : Return the product of array elements

#                             over a given axis treating Not a Numbers (NaNs) as ones

 

In [14]: d = np.array([[1, 2], [3, np.nan]])


In [15]: d

Out[15]:

array([[  1.,   2.],
        [  3.,  nan]])


In [16]: np.nanprod(d, axis=0)  # [1*3, 2*1]  ↓

Out[16]: array([ 3., 2.])


In [17]: np.nanprod(d, axis=1)  # [1*2, 3*1]  →

Out[17]: array([ 2., 3.])

 

 

 

 

 (1-2-4) NaN이 포함된 배열 원소 간 더하기 범용 함수 : np.nansum()

 

np.nansum() 함수는 NaN (Not a Numbers)을 '0'(zero)으로 간주하고 배열 원소 간 더하기를 합니다.

 

 

In [15]: d

Out[15]:

array([[  1.,   2.],
        [  3.,  nan]])

 

# (1-2-4) np.nansum() : Return the sum of array elements

#                             over a given axis treating Not a Numbers (NaNs) as zero

 

In [18]: np.nansum(d, axis=0)  # [1+3, 2+0]  ↓

Out[18]: array([ 4., 2.])


In [19]: np.nansum(d, axis=1)  # [1+2, 3+0]  →

Out[19]: array([ 3., 3.])

 

 

 

 

 (1-2-5) 배열 원소 간 누적 곱하기 범용 함수 : np.cumprod()

 

axis=0 이면 같은 행(column)의 위에서 아래 방향으로 배열 원소들을 누적(cumulative)으로 곱해 나가며, axis=1 이면 같은 열(row)에 있는 배열 원소 간에 왼쪽에서 오른쪽 방향으로 누적으로 곱해 나갑니다.

 

 

In [20]: e = np.array([1, 2, 3, 4])


In [21]: e

Out[21]: array([1, 2, 3, 4])


In [22]: f = np.array([[1, 2, 3], [4, 5, 6]])


In [23]: f

Out[23]:

array([[1, 2, 3],
        [4, 5, 6]])

 

 

# (1-2-5) np.cumprod() : Return the cumulative product of elements along a given axis

In [24]: np.cumprod(e)  # [1, 1*2, 1*2*3, 1*2*3*4]

Out[24]: array([ 1, 2, 6, 24], dtype=int32)


In [25]: np.cumprod(f, axis=0)  # [[1, 2, 3], [1*4, 2*5, 3*6]]  ↓

Out[25]:

array([[ 1,  2,  3],
        [ 4, 10, 18]], dtype=int32)


In [26]: np.cumprod(f, axis=1)  # [[1, 1*2, 1*2*3], [4, 4*5, 4*5*6]]  →

Out[26]:

array([[  1,   2,   6],
        [  4,  20, 120]], dtype=int32)

 

 

 

 

 (1-2-6) 배열 원소 간 누적 합 구하기 범용 함수 : np.cumsum()

 

axis=0 이면 같은 행(column)의 위에서 아래 방향으로 배열 원소들을 누적(cumulative)으로 합해 나가며, axis=1 이면 같은 열(row)에 있는 배열 원소 간에 왼쪽에서 오른쪽 방향으로 누적으로 합해 나갑니다.

 

 

In [21]: e

Out[21]: array([1, 2, 3, 4])

 

# (1-2-6) np.cumsum(a, axis) : Return the cumulative sum of the elements along a given axis

 

In [27]: np.cumsum(e)  # [1, 1+2, 1+2+3, 1+2+3+4]

Out[27]: array([ 1,  3,  6, 10], dtype=int32)

 

 

In [23]: f

Out[23]:

array([[1, 2, 3],
        [4, 5, 6]])

 

In [28]: np.cumsum(f, axis=0)  # [[1, 2, 3], [1+4, 2+5, 3+6]]  ↓

Out[28]:

array([[1, 2, 3],
        [5, 7, 9]], dtype=int32)


In [29]: np.cumsum(f, axis=1)  # [[1, 1+2, 1+2+3], [4, 4+5, 4+5+6]]  →

Out[29]:

array([[ 1,  3,  6],
        [ 4,  9, 15]], dtype=int32)

 

 

 

 

  (1-2-7) 배열 원소 간 n차 차분 구하기 : np.diff()

 

 

# (1-2-7) diff(a, n, axis) : Calculate the n-th discrete difference along given axis

 

In [30]: g = np.array([1, 2, 4, 10, 13, 20])


In [31]: g

Out[31]: array([ 1, 2, 4, 10, 13, 20])

 

 

# 1차 차분 (1st order differencing)

In [32]: np.diff(g)  # [2-1, 4-2, 10-4, 13-10, 20-13]

Out[32]: array([1, 2, 6, 3, 7])

 

 

# 2차 차분 (2nd order differencing) => 1차 차분 결과 Out[32] 를 가지고 한번 더 차분

In [33]: np.diff(g, n=2)  # [2-1, 6-2, 3-6, 7-3]  <- using Out[32] array (1st order difference)

Out[33]: array([ 1, 4, -3, 4])

 

 

# 3차 차분 (3rd order differencing) => 2차 차분 결과 Out[33] 을 가지고 한번 더 차분

In [34]: np.diff(g, n=3)  # [4-1, -3-4, 4-(-3)]  <- using Out[33] array (2nd order diffenence)

Out[34]: array([ 3, -7, 7])

 

 

 

2차원 배열의 경우 axis=0 이면 같은 열(column)의 아래에서 위 방향으로 차분(difference)을 하며,

axis=1 이면 같은 행(row)의 오른쪽에서 왼쪽 방향으로 차분을 합니다.

 

 

#---- 2 dimentional arrays

 

In [35]: h = np.array([[1, 2, 4, 8], [10, 13, 20, 15]])


In [36]: h

Out[36]:

array([[ 1,  2,  4,  8],
        [10, 13, 20, 15]])

 

In [37]: np.diff(h, axis=0)  # [10-1, 13-2, 20-4, 15-8] ↑

Out[37]: array([[ 9, 11, 16, 7]])


In [38]: np.diff(h, axis=1)  # [[2-1, 4-2, 8-4], [13-10, 20-13, 15-20]] ←

Out[38]:

array([[ 1,  2,  4],
        [ 3,  7, -5]])

 

 

# n=2 이면 1차 차분 결과인 Out[38] 배열에 대해 한번 더 차분

 

In [39]: np.diff(h, n=2, axis=1)  [[2-1, 4-2], [7-3, -5-7]] ←

Out[39]:

array([[  1,   2],
        [  4, -12]])

 

 

 

 

 (1-2-8) 차분 결과를 1차원 배열(1 dimensional array)로 반환해주는 함수 : ediff1d()

 

2차원 배열에 대한 차분인 np.diff(h, axis=1) 의 경우 Out[38] 처럼 2차원 배열을 반환합니다. 반면에 ediff1d(h) 함수를 사용하면 Out[41] 처럼 차분 결과를 1차원 배열로 반환합니다.

 

 

# (1-2-8) ediff1d(ary[, to_end, to_begin])

#           : The differences between consecutive elements of an array

 

In [31]: g

Out[31]: array([ 1, 2, 4, 10, 13, 20])

 

In [40]: np.ediff1d(g)

Out[40]: array([1, 2, 6, 3, 7])

 

 

# 2 dimensional array

 

In [36]: h

Out[36]:

array([[ 1,  2,  4,  8],
        [10, 13, 20, 15]])

 

# The returned array is always 1D

In [41]: np.ediff1d(h)

Out[41]: array([ 1, 2, 4, 2, 3, 7, -5])  # 1D array, not 2D array

 

 

 

np.ediff1d() 함수의 시작부분과 끝 부분의 값을 to_begin, to_end 로 설정해줄 수도 있습니다.

 

 

In [42]: np.ediff1d(h, to_begin=np.array([-100, -99]), to_end=np.array([99, 100]))

Out[42]: array([-100, -99, 1, 2, 4, 2, 3, 7, -5, 99, 100])

 

 

 

 

  (1-2-9) 기울기(gradient) 구하기 범용 함수 : np.gradient()

 

gradient는 1차 편미분한 값들로 구성된 배열입니다. 아래 예제에 np.gradient() 함수가 어떻게 계산되는지를 수식을 적어놓았으니 참고하시기 바랍니다.  말로 설명하기가 쉽지가 않네요. ^^; 

 

 

In [31]: g

Out[31]: array([ 1, 2, 4, 10, 13, 20])

 

 

# [(2-1), {(2-1)+(4-2)}/2, {(4-2)+(10-4)}/2, {(10-4)+(13-10)}/2, {(13-10)+(20-13)}/2, (20-13)]

In [43]: np.gradient(g)

Out[43]: array([ 1. , 1.5, 4. , 4.5, 5. , 7. ])

 


# N scalars specifying the sample distances for each dimension

# x축 1단위가 '2'이므로 양쪽 옆으로 x축 변화에 따른 y값 변화를 보는 것이므로 2(단위)*2(방향)으로 나누어 줌

# [(2-1)/2, {(2-1)+(4-2)}/2*2, {(4-2)+(10-4)}/2*2, {(10-4)+(13-10)}/2*2, {(13-10)+(20-13)}/2*2, (20-13)/2] 

In [44]: np.gradient(g, 2)

Out[44]: array([ 0.5 , 0.75, 2. , 2.25, 2.5 , 3.5 ])

 


# Gradient is calculated using N-th order accurate differences at the boundaries

# 양 옆에만 2차 차분 : 1 - (1.5 -1) = 0.5,   7 + (7-5) = 9

In [45]: np.gradient(g, edge_order=2)

Out[45]: array([ 0.5, 1.5, 4. , 4.5, 5. , 9. ])

 

 

 

아래는 2차원 배열에 대한 gradient 구하는 예제입니다. np.gradient(h, axis=0)과 np.gradient(h, axis=1)을 짬뽕해 놓은 것이 np.gradient(h) 라고 보면 되겠습니다.  gradient 방법은 위의 1차원에서 소개한 방법과 같습니다.

 

 

# 2 dimensional array

 

In [36]: h

Out[36]:

array([[ 1,  2,  4,  8],
        [10, 13, 20, 15]])

 

 

# the first array stands for the gradient in rows and the second one in columns direction

In [46]: np.gradient(h)

Out[46]:

[array([[  9.,  11.,  16.,   7.],
         [  9.,  11.,  16.,   7.]]),

 array([[ 1. ,  1.5,  3. ,  4. ],
         [ 3. ,  5. ,  1. , -5. ]])]

 


# The axis keyword can be used to specify a subset of axes of which the gradient is calculated

 

In [47]: np.gradient(h, axis=0)  # ↑

Out[47]:

array([[  9.,  11.,  16.,   7.],
        [  9.,  11.,  16.,   7.]])


In [48]: np.gradient(h, axis=1)  # ←

Out[48]:

array([[ 1. ,  1.5,  3. ,  4. ],
        [ 3. ,  5. ,  1. , -5. ]])

 

 

 

다음번 포스팅에서는 지수함수, 로그함수, 삼각함수에 대해서 다루어보겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅부터는 몇 번에 나누어서 로그함수, 삼각함수, 사칙연산 함수 등과 같이 일반적으로 많이 사용되는 범용 함수 (universal functions)들에 대해서 소개하겠습니다.

 

Python에서 범용 함수를 지원하는 모듈이 여러개 있습니다. 

 

Pytho 배울 때 초반에 배우는 math module은 실수(real number)에 대해서만 범용함수를 지원하며, cmath module 은 복소수(complex number) 까지 범용함수를 지원합니다. numpy module은 실수, 복소수, 복소수 행렬 (complex matrix)의 원소 간 범용 함수를 모두 지원하므로 사용 범위가 가장 넓어 매우 유용합니다.  배열의 원소간 연산을 위해 NumPy의 Ufunc 함수는 쓸모가 많습니다. NumPy는 맥가이버 칼 같다고나 할까요.

 

[ Python modules for Universal Functions ]

 

 

 

 

NumPy 범용 함수는 몇 개의 배열에 대해 적용이 되는지에 따라서

 - (1) 1개의 배열에 적용하는 Unary Universal Functions (ufuncs)

 - (2) 2개의 배열에 대해 적용하는 Binary Universal Functions (ufuncs)

으로 구분할 수 있습니다.

 

범용함수 종류가 너무 많아서 포스팅에 한꺼번에 소개하기가 버거우므로, 서너번에 나누어서 Unary Universal Functions를 먼저 소개하고, 다음으로 Binary Ufuncs  순서로 알아보겠습니다.

 

 

 

 

  (1-1) 올림 혹은 내림 범용 함수 (round universal functions)

 

비슷비슷한 함수들이 여러개 있는데요, 말로 설명하는 것보다 예를 자세히 살펴보고 비교해보는 것이 이해하기에 쉽고 빠를 것 같습니다.

 

 

# import module and making an array

In [1]: import numpy as np


In [2]: a = np.array([-4.62, -2.19, 0, 1.57, 3.40, 4.06])


In [3]: a

Out[3]: array([-4.62, -2.19, 0. , 1.57, 3.4 , 4.06])

 

 

 

 (1-1-1) np.around(a) : 0.5를 기준으로 올림 혹은 내림

 

 

# np.around(a) : Evenly round to the given number of decimals

 

In [3]: a

Out[3]: array([-4.62, -2.19, 0. , 1.57, 3.4 , 4.06])

 

In [4]: np.around(a)

Out[4]: array([-5., -2., 0., 2., 3., 4.]) 

 

 

 

 

 (1-1-2) np.round_(a, N) : N 소수점 자릿수까지 반올림

 

  

# np.round_(a, n) : Round an array to the given number of decimals

 

In [3]: a

Out[3]: array([-4.62, -2.19, 0. , 1.57, 3.4 , 4.06])

 

In [5]: np.round_(a, 1)

Out[5]: array([-4.6, -2.2, 0. , 1.6, 3.4, 4.1]) 

 

 

 

 

 (1-1-3) np.rint(a) : 가장 가까운 정수로 올림 혹은 내림

 

 

# round elements to the nearest integer

 

In [3]: a

Out[3]: array([-4.62, -2.19, 0. , 1.57, 3.4 , 4.06])

 

In [6]: np.rint(a)

Out[6]: array([-5., -2., 0., 2., 3., 4.])

 

 

 

 

 (1-1-4) np.fix(a) : '0' 방향으로 가장 가까운 정수로 올림 혹은 내림

 

 

# Round to nearest integer towards zero

 

In [3]: a

Out[3]: array([-4.62, -2.19, 0. , 1.57, 3.4 , 4.06])

 

In [7]: np.fix(a)

Out[7]: array([-4., -2., 0., 1., 3., 4.])

 

 

 

 

 (1-1-5) np.ceil(a) : 각 원소 값보다 크거나 같은 가장 작은 정수 값 (천장 값)으로 올림

 

 

# the smallest integer greater than or equal to each element 

 

In [3]: a

Out[3]: array([-4.62, -2.19, 0. , 1.57, 3.4 , 4.06])

 

In [8]: np.ceil(a)

Out[8]: array([-4., -2., 0., 2., 4., 5.])

 

 

 

 

 (1-1-6) np.floor(a) : 각 원소 값보다 작거나 같은 가장 큰 정수 값 (바닥 값)으로 내림

 

 

# the largest integer less than or equal to each element

 

In [3]: a

Out[3]: array([-4.62, -2.19, 0. , 1.57, 3.4 , 4.06])

 

In [9]: np.floor(a)

Out[9]: array([-5., -3., 0., 1., 3., 4.])

 

 

 

 

 (1-1-7) np.trunc(a) : 각 원소의 소수점 부분은 잘라버리고 정수값만 남김

 

 

# Return the truncated value of the input, element-wise

 

In [3]: a

Out[3]: array([-4.62, -2.19, 0. , 1.57, 3.4 , 4.06])

 

In [10]: np.trunc(a)

Out[10]: array([-4., -2., 0., 1., 3., 4.])

 

 

 

다음번 포스팅에서는 단일 배열 범용 함수의 두번째 순서로 합(sums), 곱(products), 차분(difference), 미분(gradient) 함수에 대해서 알아보도록 하겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

728x90
반응형
Posted by Rfriend
,