본문 바로가기
Daily/Daily_2 후기

[패스트캠퍼스 후기] 데이터 처리를 위한 Python (Numpy) 내용 정리 및 요약 - 2

by 와우멍 2020. 10. 18.

 안녕하세요 와우멍입니다.

 코로나 시국에 회사 내/외부 교육들이 모두 취소되면서, 복지차원으로 패스트캠퍼스의 온라인 강의를 들을 기회를 얻게 되었습니다.

 연구하면서 필요한 것들을 덕지덕지 찾아가며 해왔었기에, 한번쯤은  체계적으로 배워보고 싶었는데 수강신청 성공한 게 너무 행복하네요 허헛..

 강의의 명칭은 "머신러닝과 데이터분석 AtoZ"입니다.

각 챕터에 대한 설명은 아래와 같습니다. 요건 좀 기니까 접어둘께요! 필요한 분들 펼쳐서 봐주세요:-)

 

01. Python Programming 기초
02. 데이터 수집을 위한 Python (Crawling) 
03. 데이터 처리를 위한 Python (Numpy) 
04. 데이터 분석을 위한 Python (Pandas) 
05. Machine learning의 개념과 종류 
06. 회귀분석 
07. 기본적인 Machine learning 모형 
08. 앙상블 기법의 종류와 원리 
09. 클러스터링 
10. 불균형 데이터 
11. 빅콘테스트 Review 
12. 딥러닝 
13~17. [Project] 

오늘은 Chapter3. Numpy에 대해서 완강하며 정리한 내용을 포스팅하겠습니다.

 

6. ndarray 기본 함수 사용하기

개요에서 이야기했던 numpy가 갖는 장점인 여러 내장 함수들의 사용을 본격적으로 이야기하기 시작합니다.

- 사칙연산 함수인 np.add(성분1, 성분2), np.subtract(성분1, 성분2), np.multiply(성분1, 성분2), np.divide(성분1, 성분2)는 직관적이다. 여기서 numpy가 갖는 가장 큰 장점은 바로 Element-wised calculation이 된다는 것이다. 

 (fortran같은 기본언어 사용할 때는, loop돌려서 성분을 하나씩 불러와서 계산해주고 다시 입력해주고 했었는데 그럴필요가 없다는 것!)

 - 또한, 평균이나 표준편차, 최대값, 최소값 등을 계산하는 것도 한줄에 가능하다.

 np.mean(행렬): 행렬 모든 성분들의 평균 계산

np.max(행렬): 행렬 내의 성분들 중 최대값 출력

np.argmax(행렬): 최대값 갖는 성분의 위치 출력

np.sum(행렬): 성분들의 합

np.cumsum(행렬): 누적합계 (histogram같은거 그릴때 편할듯)

 - np.any(조건) 은 조건을 만족시키는 성분이 한개라도 있으면 True를 반환,

 - np.all(조건) 은 조건을 모두 만족시켜야 True를 반환.

 - np.where(성분)은 개인적으로 연구할 때 가장 많이 쓰던 함수!

단순히 np.where(조건) 으로만 하면 조건이 참이되는 성분들의 인덱스들을 뱉어주지만,

np.where(조건, 값1, 값2) 로 사용하면, 조건이 성립하는 곳은 값1을, 조건이 만족하지 않는 성분들은 값2로 치환하여 반환한다.

 

7. axis 이해 및 axis를 파라미터로 갖는 함수 활용하기

 - numpy의 함수들 중 다수는 axis라는 특성을 이용하여 계산범위를 한정시킬 수 있다.

1차원에서는 결과가 같지만,

2차원에 대해 적용한 예시를 보면

axis=0으로 설정하여 한 결과는 첫번째 성분(2차원 기준 행)쪽, 아래쪽으로 꾹 눌러서 계산을 했고

axis=1로 설정하면 두번째 성분(2차원 기준 열)쪽, 왼쪽으로 꾹 눌러서 계산을 했다.

3차원에 대해 적용한 예시를 보면

 axis=0으로 하면, 첫번째 성분쪽으로 눌러서 계산을 하니 (3, 4, 3) 사이즈가 (4, 3) 사이즈가 되고

 axis=1로 하면, 두번째 성분쪽으로 눌러지니 (3, 4, 3)이 (3, 3) 사이즈가 되고

 axis=2로 하면, 세번째 성분쪽으로 눌러져서 (3, 4, 3)이 (3, 4) 사이즈가 된다.

 

8. Broadcasting 이해 및 활용하기.

 - broadcasting이라는 특성은 앞서 언급한 element-wised calculation과 연관지어서 생각하면 이해가 쉬울 듯하다.

형태가 같은 행렬간의 사칙연산은 직관적으로 이해가능하고, 상수배도 쉽게 받아들일 수 있을 것이다.

문제는 형태가 다른 행렬간의 연산..!

이때는 성분 중 일부가 맞아야 한다. 2차원 행렬 기준으로 뒷쪽 성분이 일치해야 broadcasting이 됨.

위의 예시에서처럼 (4, 3) 행렬과 (3,) 행렬은 자동으로 연산이 되어 (3,)의 값들이 각 행에 연산이 되지만,

(4, 3)행렬과 (4,)의 행렬은 연산이 되지 않는다.

 

9. Boolean indexing로 조건에 맞는 데이터 선택하기.

 - boolean이라는 것은 True/ False를 이야기 함. 즉, 조건에 대한 결과를 다시 index로 사용할 수 있다는 것이다.

위 예시에서 even_mask = (x%2==0) 는 2로 나눠서 0이 되는지의 여부를 담고있는 boolean array가 된다.

그래서 이걸 x의 index로 쓰게되면, x 중 짝수만 출력되는 것!

줄여서 그냥 바로 x[x>30]으로 쓰면 30보다 큰 값들만 출력이 된다.

 - 조건을 여러개 적용하고 싶다면, 가볍게 & (and) 와 | (or)로 조건들을 엮어주면 된다. 다만, 일반 논리 연산자인 and/ or는 array계산에서 못쓴다.

- 그리고 True는 1, False는 0의 값으로 읽혀지기 때문에 아래의 예시처럼 boolean index들의 summation을 통해 참인 성분이 몇개인지를 바로 계산할 수 있다.

 

10. linalg 서브모듈 사용하여 선형대수 연산하기.

 - numpy는 선형대수 계산 함수들도 내장되어 있어, 예쩐에 과제할 때 매우매우 유용하게 사용했었다.

3x3이상 함수의 array의 역행렬이나 행렬계산할 때 정말 노가다인데, numpy를 이용하면 몇초 만에 가능하다!!

*여기서 np.multiply(A,B)는 앞서 이야기한 broadcasting으로 성분에 곱하기가 되는 건데, 행렬곱(dot)을 하기 위해서는 np.dot(A, B)나 A@B로 수행할 수 있다. (다만 @을 이용한 연산은 정방행렬에서만 가능)

위에서처럼 인버스나 행렬곱은 물론, 솔루션도 계산가능하다. 

np.alllcose(행렬1, 행렬2)는 두 행렬의 각 성분을 일대일로 비교해줘서 거의 같으면 True를 반환해준다 (0에 가까운 값)

 

11. ndarray 데이터를 이용하여 다양한 그래프 표현하기

- 데이터를 그림으로 표현할 때는 matplotlib을 사용하면 된다. 

보통 import matplotlib.pyplot as plt 로 불러와서 plt.~ 로 사용!

plt.figure() #도화지를 꺼내와서 준비

plt.xlabel('X', color = 'white') #x축 설명에 'X'라고 쓰고 글씨색은 하얀색

plt.ylabel('Y', color = 'white') #y축 설명에 'Y'라고 쓰고 글씨색은 하얀색

plt.title('Test', color ='white') #위에 제목을 'Test'라고 달고 글씨색은 하얀색

plt.plot(x,y) #x, y의 그래프를그림

plt.grid() #격자무늬를 활성화

plt.xlim(0,20) #x의 범위는 [0, 20]

plt.ylim(0,200) # y의 범위는 [0, 200]

plt.figure()  #그림을 그릴 도화지를 불러옴

plt.subplot(2,2,1) #도화지를 2x2 등분하고 그 중 1번째 칸을 선택

plt.plot(x,y, 'r:') #1번째 칸에 빨간색 점선으로 그린다.

이런 식으로 해석하면 된다.

 

12. 연습문제

 1. 로또번호 생성기

나는 np.random.randint를 사용했는데... 이건 생각해보니 복원추출이네 ㅠㅠ choice를 이용해야 복원/비복원을 선택할 수 있음..

2. 원주율 계산

내 풀이) sample수가 많을수록 실제값에 가까워지니 일단 이걸 변수 n으로 받고,

0부터 1까지를 n^2개로 쪼갠 행렬을 만들고

여기서 랜덤하게 [x, y] 좌표를 생성하여, 이 샘플 중에 사분원에 들어오는 점들의 개수를 더한다.

그럼 pi * (r^2) / 4 = 사분원 가 되야 하니 

pi = 사분원 * 4 / (1^2) 이 되어 pi의 근사값을 알 수 있다.

해설) 답안에서는 이걸 좀더 간소화했음. [x,y]뽑는걸 그냥 한줄로 압축해서 더 편하게 만들었음.

그래서 결과는 같지만, 소요시간이 차이가 난다.

 

혹시라도 질문 혹은 수정이나 보완 필요한 부분 있으면 댓글 부탁드립니다 :-)

댓글