[오늘의 일지]
파이썬 EDA 실시간 강의 - Numpy, Pandas
[상세 내용]
파이썬 EDA
EDA
- 정의 : 우선 수업을 듣기에 앞서서 EDA란 단어를 몰라서 찾아봤습니다. EDA는 Exploratory Data Analysis의 약어로 탐색적 데이터 분석이라는 뜻을 가지고 있습니다. 처음 시작은 벨연구소의 수학자 존 튜키가 개발한 데이터분석 방법론으로, 데이터를 다양한 각도에서 관찰하고 이해하는 모든 과정을 말한다고 합니다.
Numpy
- Numpy는 Numerical computing with Python의 약어로서 수치연산 및 벡터 연산에 최적화된 파이썬 라이브러리를 의미한다고 합니다. Numpy는 2005년에 만들어졌으며 100%로 오픈소스입니다.
- Numpy의 주요 특징은 파이썬이 가지고 있는 취약한 수치 연산 부분에서 안정성을 보장합니다. 그렇기 때문에 N차원 실수값 연산에 최적화되어 있다고 합니다. 이 말은 N개의 실수로 이루어진 벡터 연산에 최적화되어 있다는 말과 같은 말입니다.
- Numpy는 사용 시 numpy array 구조로 사용이 됩니다. 이 구조는 파이썬에서 사용하는 리스트의 구조와 비슷한 구조를 가지고 있지만 세부적인 특징에서는 C언어의 array 구조와 동일한 개념이라 합니다. 아래는 numpy array의 1차원, 2차원 , 3차원 구조를 그림으로 알기 쉽게 표현해 놓은 것입니다.
- Numpy의 데이터 구조는 일반 파이썬과 다른 구조를 가지고 있다.
- Numpy 기초 연습
# numpy 라이브러리를 불러옵니다.
import numpy as np
# 파이썬 리스트 선언
data = [1, 2, 3, 4]
# 파이썬 2차원 리스트(행렬) 선언
data2 = [[1, 2],
[3, 4]]
# 파이썬 list를 numpy array로 변환합니다.
# numpy array를 만드는 방식의 대부분은 파이썬 리스트를 np.array로 변환하는 방식입니다.
arr = np.array(data)
arr
>>>
array([1, 2, 3, 4])
# 2차원 리스트를 np.array로 만듭니다.
arr2 = np.array(data2) # data2라는 리스트를 numpy array로 만들어라.
arr2
>>>
array([[1, 2],
[3, 4]])
- 숫자를 자동으로 생성하는 array
# 0부터 9까지 숫자를 자동으로 생성한 array
# np.arange(0, 10)
# np.zeros(5)
# np.ones(7)
# np.empty(5) # uninitialized
np.linspace(1, 50, 50) # 0부터 50까지의 범위에서 50개의 등분을 찾아주는 함수
- Numpy array 연산
# v1 = (1, 2, 3), v2 = (4, 5, 6) 벡터 2개 생성하기.
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
# vector addition
v1 + v2
>>>
array([5, 7, 9])
# vector subtraction
v1 - v2
>>>
array([-3, -3, -3])
# (not vector operation) elementwise multiplication
v1 * v2
>>>
array([ 4, 10, 18])
# (not vector operation) elementwise division
v1/v2
>>>
array([0.25, 0.4 , 0.5 ])
# dot product (내적)
v1 @ v2
>>>
32
- Numpy의 Broadcast : 크기가 다른(차원이 다른) numpy array를 연산할 때, 자동으로 연산을 전파(broadcast)해주는 기능. 행렬곱 연산을 할 때 편리하다.
arr1 = np.array([1, 0, 0]) # 1d array
arr3 = np.array([[1], [0], [0]]) # 2d array
arr2 = np.array([[1, 2, 3],
[4, 5, 6]]) # 2d array
# Shape은 array의 구조를 알려주는 함수이다
print(arr1.shape)
print(arr2.shape)
print(arr3.shape)
>>>
(3,)
(2, 3)
(3, 1)
# 2개의 array를 더해보면? [arr1 + arr2[0], arr 1 + arr2[1]]의 형태로 자동으로 더해준다
arr1 + arr2
>>>
array([[2, 2, 3],
[5, 5, 6]])
# 2개의 array를 곱해보면?
arr1 * arr2
>>>
array([[1, 0, 0],
[4, 0, 0]])
- Universal Function : broadcast 기능의 확장으로서 numpy array의 모든 원소에 동일한 함수를 반복문으로 적용한 것과 같은 효과를 내는 기능입니다.
arr = np.array([1., 2., 3., 4.])
f = lambda x : 1/x
for i in range(len(arr)):
arr[i] = f(arr[i])
print(arr)
# numpy에서는 그냥 이렇게 표현이 가능하다
1/arr
- Fancy Indexing : Numpy array는 list의 indexing을 확장하여 다양한 조건에서의 indexing을 지원한다.
arr1 = np.arange(10)
arr1
>>>
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 첫번째 원소
arr1[0]
>>>0
# 마지막 원소
arr1[-1]
>>>9
# 앞에서부터 원소 3개 slicing
arr1[:3]
>>>
array([0, 1, 2])
arr2 = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
arr2
# arr2.shape >>> (3, 4)
## np.array.shape의 규칙 : 괄호 앞에서부터 제일 바같 []의 원소의 개수부터 안쪽 []까지 차례대로 적는다.
# arr2의 2row, 3column 원소 = 7
arr2[1][2]
arr2[1, 2]
>>>7
# arr2의 세번째 column [3, 7, 11]
arr2[:, 2]
>>>
array([ 3, 7, 11])
# arr2의 두번째 row
arr2[1, :]
>>>
array([5, 6, 7, 8])
# arr2에서 두번째 row중에서 6보다 큰 원소들 찾기
mask = arr2[1, :] >6 # filter : True 위치에 있는 데이터만 출력
arr2[1, :][mask] # mask를 indexing에 사용하려면, mask 조건에 해당하는 원소만 출력됨.
>>>
array([7, 8])
# arr2의 두번째 column중에서 6보다 큰 원소들 찾기
# arr2p[row에 대한 조건, col에 대한 조건]
arr2[arr2[:, 1]> 6, 1]
# [DEBUG] mask의 크기가 내가 적용할 대상의 크기와 동일한지 확인.
>>>
array([10])
arr2[arr2[:, 0]> 8 # 첫번째 column에서 8보다 큰 원소가 있는 row를 출력하세요(이 조건에 하나라도 만족하지 못하면 출력안한다.) ,
arr2[[False, False, True]] 3번째 행을 출력
arr2[2] # True인 원소만 출력
>>>
array([[ 9, 10, 11, 12]]) # 위에 세개 다 같은 값
Pandas
- 판다스(Pandas)는 파이썬 데이터 처리를 위한 라이브러리입니다. 파이썬을 이용한 데이터 분석과 같은 작업에서 필수 라이브러리로 알려져 있습니다. 판다스를 사용하면 자신이 사용하는 데이터 자료를 보기도 깔끔하고 관리하기도 쉽게 이용할 수 있다고 합니다. 그리고 수업시간에 주의를 준 것이 있는데 판다스 버전은 1.5.3 이하로 사용하라고 말했습니다. 2.0 이상의 버전부터는 바뀐 부분이 있어서 적용이 안 되는 부분이 많다고 했습니다.
- Pandas 기초 연습
import pandas as pd
# pandas 라이브러리를 불러옵니다. pd를 약칭으로 사용합니다.
pd.Series([1, 3, 5, 6, 8]) # index, values(data), dtype
>>>
0 1
1 3
2 5
3 6
4 8
dtype: int64
# 12x4 행렬에 1부터 48까지의 숫자를 원소를 가지고,
# index는 2023-08-01부터 시작하고, coulmns은 순서대로 X1, X2, X3, X4로 하는 DataFrame 생성
df = pd.DataFrame(data=np.arange(1, 49).reshape(12, 4), # (48, ) -> (12, 4)
index=pd.date_range(start='20230801', end='20230812' , freq = 'D'),
columns=["X1", "X2", "X3", "X4"])
df
>>>
# dataframe columns
df.columns
>>>
Index(['X1', 'X2', 'X3', 'X4'], dtype='object')
# dataframe values
df.values
>>>
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24],
[25, 26, 27, 28],
[29, 30, 31, 32],
[33, 34, 35, 36],
[37, 38, 39, 40],
[41, 42, 43, 44],
[45, 46, 47, 48]])
# 특정 column을 가져오기
df["X1"]
# df['2023-08-01'] # not column name
>>>
2023-08-01 1
2023-08-02 5
2023-08-03 9
2023-08-04 13
2023-08-05 17
2023-08-06 21
2023-08-07 25
2023-08-08 29
2023-08-09 33
2023-08-10 37
2023-08-11 41
2023-08-12 45
Freq: D, Name: X1, dtype: int32
# X1 column에 2 더하기 (universal function 지원)
df['X1'] + 2
>>>
2023-08-01 3
2023-08-02 7
2023-08-03 11
2023-08-04 15
2023-08-05 19
2023-08-06 23
2023-08-07 27
2023-08-08 31
2023-08-09 35
2023-08-10 39
2023-08-11 43
2023-08-12 47
Freq: D, Name: X1, dtype: int32
- Dataframe 기초 method
# dataframe의 맨 위 다섯줄을 보여주는 head()
df.head() # 디폴트값이 5줄인데 ()안에 원하는 숫자를 쓰면 원하는 숫자만큼 나온다
>>>
X1 X2 X3 X4
2023-08-01 1 2 3 4
2023-08-02 5 6 7 8
2023-08-03 9 10 11 12
2023-08-04 13 14 15 16
2023-08-05 17 18 19 20
# 반대 개념으로는 df.tail() 있다
df.tail()
>>>
X1 X2 X3 X4
2023-08-08 29 30 31 32
2023-08-09 33 34 35 36
2023-08-10 37 38 39 40
2023-08-11 41 42 43 44
2023-08-12 45 46 47 48
# dataframe에 대한 전체적인 요약정보를 보여줍니다. index, columns, null/not-null/dtype/memory usage가 표시됩니다.
df.info()
>>>
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 12 entries, 2023-08-01 to 2023-08-12
Freq: D
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 X1 12 non-null int32
1 X2 12 non-null int32
2 X3 12 non-null int32
3 X4 12 non-null int32
dtypes: int32(4)
memory usage: 288.0 bytes
# dataframe에 대한 전체적인 통계정보를 보여줍니다.
df.describe()
>>>
X1 X2 X3 X4
count 12.000000 12.000000 12.000000 12.000000
mean 23.000000 24.000000 25.000000 26.000000
std 14.422205 14.422205 14.422205 14.422205
min 1.000000 2.000000 3.000000 4.000000
25% 12.000000 13.000000 14.000000 15.000000
50% 23.000000 24.000000 25.000000 26.000000
75% 34.000000 35.000000 36.000000 37.000000
max 45.000000 46.000000 47.000000 48.000000
# X2 column를 기준으로 (데이터를) 내림차순 정렬 ## sort with expansion
df.sort_values(by="X2", ascending=False)
>>>
X1 X2 X3 X4
2023-08-12 45 46 47 48
2023-08-11 41 42 43 44
2023-08-10 37 38 39 40
2023-08-09 33 34 35 36
2023-08-08 29 30 31 32
2023-08-07 25 26 27 28
2023-08-06 21 22 23 24
2023-08-05 17 18 19 20
2023-08-04 13 14 15 16
2023-08-03 9 10 11 12
2023-08-02 5 6 7 8
2023-08-01 1 2 3 4
- Fancy Indexing :
# pandas dataframe은 column 이름을 이용하여 기본적인 Indexing이 가능합니다.
# X1 column을 indexing
df['X3']
df.X2 # column name
>>>
2023-08-01 2
2023-08-02 6
2023-08-03 10
2023-08-04 14
2023-08-05 18
2023-08-06 22
2023-08-07 26
2023-08-08 30
2023-08-09 34
2023-08-10 38
2023-08-11 42
2023-08-12 46
Freq: D, Name: X2, dtype: int32
# dataframe에서 slicing을 이용하면 row 단위로 잘려나옵니다.
# 앞에서 3줄을 slicing 합니다.
df[:3]
>>>
X1 X2 X3 X4
2023-08-01 1 2 3 4
2023-08-02 5 6 7 8
2023-08-03 9 10 11 12
# df.loc는 특정값을 기준으로 indexing합니다. (key - value)
## df.loc[row에 대한 조건, col에 대한 조건]
df.loc['20230801']
>>>
X1 1
X2 2
X3 3
X4 4
Name: 2023-08-01 00:00:00, dtype: int32
# df.loc에 2차원 indexing도 가능합니다.
# df.loc[index, columns]
df.loc['20230807', 'X3'] # 특정 원소 하나 뽑기
df.loc[['20230801','20230805'],['X1','X4']] # 불연속적인 row, col 뽑기
df.loc['20230803':'20230810', 'X2':"X4"] # 연속적인 row, col 뽑기
# dataframe에 조건식을 적용해주면 조건에 만족하는지 여부를 알려주는 "mask"가 생깁니다.
# Q. df에서 X3 column에 있는 원소들중에 3의 배수만 출력해주세요!
df.X3 % 3 == 0 # boolean mask
df.loc[df.X3 % 3 == 0, 'X3' ]
# Q. df에서 X2 column에 있는 원소들 중에 20 보다 큰 원소들을 출력해주세요
df.loc[df.X2 > 20, 'X2']
>>>
2023-08-06 22
2023-08-07 26
2023-08-08 30
2023-08-09 34
2023-08-10 38
2023-08-11 42
2023-08-12 46
Freq: D, Name: X2, dtype: int32
# 2차원 리스트 indexing과 같은 원리가 되었습니다.
# integer-location based indexing ## iloc
df.iloc[2, 3]
>>>12
# iloc로 2차원 indexing을 하게되면, row 기준으로 index 3,4를 가져오고 column 기준으로 0, 1을 가져옵니다.
df.iloc[[3,4],[0,1]]
df.iloc[5:8,1:3]
# df.iloc[df.X2 > 20, 1] ## boolean mask로 indexing이 안됨.
>>>
# iloc로 2차원 indexing을 하게되면, row 기준으로 index 3,4를 가져오고 column 기준으로 0, 1을 가져옵니다.
df.iloc[[3,4],[0,1]]
df.iloc[5:8,1:3]
# df.iloc[df.X2 > 20, 1] ## boolean mask로 indexing이 안됨.
1
# iloc로 2차원 indexing을 하게되면, row 기준으로 index 3,4를 가져오고 column 기준으로 0, 1을 가져옵니다.
2
df.iloc[[3,4],[0,1]]
3
df.iloc[5:8,1:3]
4
# df.iloc[df.X2 > 20, 1] ## boolean mask로 indexing이 안됨.
X2 X3
2023-08-06 22 23
2023-08-07 26 27
2023-08-08 30 31
[마무리]
이번주차부터는 진짜로 데이터를 다루는 라이브러리인 Numpy와 Pandas에 대한 수업이 시작되었습니다. 부트캠프를 시작한 지 약 한 달 만에 데이터를 다룰 수 있는 파트까지 온 것인데요. 이제부터는 진짜 관심이 있던 분야에 대해서 시작하는 것이기 때문에 점점 흥미가 증가하는 것 같습니다.
'AI > 데이터 사이언스' 카테고리의 다른 글
[AI 부트캠프] DAY 26 - 파이썬 EDA 6 (2) | 2023.08.23 |
---|---|
[AI 부트캠프] DAY 25 - 파이썬 EDA 5 (0) | 2023.08.22 |
[AI 부트캠프] DAY 24 - 파이썬 EDA 4 (0) | 2023.08.19 |
[AI 부트캠프] DAY 23 - 파이썬 EDA 3 및 현직자 특강 (0) | 2023.08.18 |
[AI 부트캠프] DAY 22 - 파이썬 EDA 2 (0) | 2023.08.17 |
댓글