일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 데이터분석
- CNN 실습
- plot_model
- MaxPooling2D
- 인공지능
- explained AI
- learning_rate
- OneHotEncoding
- AI
- Neural Network
- AWS 입문자를 위한 강의
- NewsWhale
- Pooling Layer
- 크롤링
- pandas
- CNN
- 데이터크롤링
- 딥러닝
- kt에이블스쿨
- bias
- 모델평가
- 데이터처리
- Convolution Neural Network
- 머신러닝
- 데이터
- CRISP-DM
- CIFAR-10
- fashion mnist
- 키워드 기반 뉴스 조회
- 뉴스웨일
- Today
- Total
jjinyeok 성장일지
Python 라이브러리 # 2 pandas - 2022/08/01~2022/08/02 본문
지난 게시글에 이어 8월 1일부터 8월 2일까지 배운 데이터분석에서 중요한 라이브러리 중 하나인 pandas 라이브러리를 정리하고자 한다. 이전에 나는 pandas에 대해 드문드문 알고 있었지만 이번 강의를 통해 pandas에 대한 정리가 확실히 되었다.
1. 판다스의 구조
판다스는 데이터프레임(Dataframe)과 시리즈(Series)로 구성할 수 있다. 데이터프레임에서 열(정보)를 띄어낸 것이 시리즈이고 반대로 시리즈의 집합체가 데이터프레임이다.
먼저 데이터프레임을 살펴보도록 하자. 데이터프레임은 관계형 데이터베이스의 테이블 또는 엑셀 시트와 같은 2차원 구조 형태이다. 앞선 게시글의 분석할 수 있는 데이터의 모양과 같다. 먼저 행은 각각의 데이터 관측치를 의미한다. 각각의 행은 분석단위가 된다. 열은 요인(Feature)과 결과(Target)을 포함한 변수 속성을 의마한다. 각각의 열은 정보가 된다.
다음으로 시리즈는 하나의 정보에 대한 데이터들의 집합을 의미한다. 즉 데이터프레임에서 하나의 열을 띄어낸 1차원 구조의 정보이다. 데이터를 분석할 때는 시리즈보다 데이터프레임이 더 중요하다.
2. 라이브러리 불러오기
먼저 pandas 라이브러리를 불러와 사용해야한다.
import pandas as pd
3. 데이터프레임 만들기
데이터프레임을 만드는 방법으로 pd.DataFrame() 함수를 사용하여 만드는 방법과 pd.read_csv() 함수를 통해 csv파일을 읽어와 만드는 방법 등이 있다.
먼저 pd.DataFrame() 함수를 사용하여 딕셔너리 자료형이나 JSON 자료형 등을 데이터프레임으로 만드는 과정은 다음과 같다.
df = pd.DataFrame([{'name': 'jjinyeok', 'major': 'CE'}, {'name': 'gildong', 'major': 'BA'}])
print(df)
# name major
# 0 jjinyeok CE
# 1 gildong BA
다음으로 read_csv()함수를 사용하여 CSV 파일을 읽어와 데이터프레임으로 만드는 과정은 다음과 같다. 가장 일반적인 방법으로 잘 알아두자. URL을 통해서 CSV 파일을 읽어올 수도 있고 로컬에 있는 CSV 파일을 직접 읽어올 수도 있다.
titanic = pd.read_csv('titanic.csv')
print(titanic.head(3))
# PassengerId Survived
# 0 892 0
# 1 893 0
# 2 894 0
read_csv 함수에는 CSV파일의 경로말고도 몇개의 option들을 추가로 입력할 수 있다.
- sep: 구분자 지정 (default = ,(콤마))
- header: 헤더가 될 행 번호 지정 (default = 0)
- index_col: 인덱스 열 지정 (default = False)
- names: 열 이름으로 사용할 문자열 리스트
- skiprows: 처음 몇 줄을 무시할 것인지 지정
4. 데이터프레임 정보 확인하기
데이터프레임 정보를 확인하기 위해 데이터 탐색이 필요하다.
- head 메서드: 앞쪽 데이터 확인 (default = 5)
print(titanic.head())
# PassengerId Survived
# 0 892 0
# 1 893 0
# 2 894 0
# 3 895 1
# 4 896 0
print(titanic.head(3))
# PassengerId Survived
# 0 892 0
# 1 893 0
# 2 894 0
- tail 메서드: 뒤쪽 데이터 확인 (default = 5)
print(titanic.tail())
# PassengerId Survived
# 413 1305 0
# 414 1306 1
# 415 1307 0
# 416 1308 0
# 417 1309 1
- shape 속성: 데이터프레임 모양 확인 -> (행수, 열수) 형태
print(titanic.shape)
# (418, 2)
- columns 속성: 열 이름 확인
print(titanic.columns)
# Index(['PassengerId', 'Survived'], dtype='object')
- index 속성: 인덱스 정보 확인
print(titanic.index)
# RangeIndex(start=0, stop=418, step=1)
- values 속성: 값 확인 -> 값만 떼어내서 NumPy 배열 형식으로 반환
print(titanic[:5].values)
# [[892 0]
# [893 0]
# [894 0]
# [895 1]
# [896 0]]
- dtypes 속성: 열 확인
print(titanic.dtypes)
# PassengerId int64
# Survived int64
# dtype: object
- info 메서드: 인덱스, 열, 값 개수 데이터 형식 정보 등 확인
print(titanic.info())
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 418 entries, 0 to 417
# Data columns (total 2 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 PassengerId 418 non-null int64
# 1 Survived 418 non-null int64
# dtypes: int64(2)
# memory usage: 6.7 KB
- describe 메서드: 기초 통계 정보 확인
print(titanic.describe())
# PassengerId Survived
# count 418.000000 418.000000
# mean 1100.500000 0.366029
# std 120.810458 0.482295
# min 892.000000 0.000000
# 25% 996.250000 0.000000
# 50% 1100.500000 0.000000
# 75% 1204.750000 1.000000
# max 1309.000000 1.000000
또한 데이터를 정렬하여 데이터 정보를 확인할 수 있다. 정렬은 sort_index 메서드를 통해 인덱스를 기준으로 정렬하는 방식과 sort_values 메서드를 사용해 특정 열을 기준으로 정렬하는 것이 가능하다. 두 메서드 정렬 방법에 대해 사용하는 옵션이 동일한데 ascending=True (default) 옵션을 사용해 오름차순 정렬이 가능하고 ascending=False 옵션을 사용해 내림차순 정렬이 가능하다. 과정은 다음과 같다. 추가적으로 sort_values 메서드는 단일 열 정렬 뿐 아니라 복합 열 정렬도 지원함을 기억하도록 하자.
# sort_index를 통해 정렬하기
print(titanic.sort_index(ascending=False))
# PassengerId Survived
# 417 1309 1
# 416 1308 0
# 415 1307 0
# 414 1306 1
# 413 1305 0
# .. ... ...
# 4 896 0
# 3 895 1
# 2 894 0
# 1 893 0
# 0 892 0
# sort_values를 통해 정렬하기
print(titanic.sort_values(by=['Survived', 'PassengerId'], ascending=[False, True]))
# PassengerId Survived
# 3 895 1
# 8 900 1
# 12 904 1
# 14 906 1
# 15 907 1
# .. ... ...
# 407 1299 0
# 412 1304 0
# 413 1305 0
# 415 1307 0
# 416 1308 0
고유값을 확인하는 것을 통해 데이터 정보를 확인할 수 있다. unique 메서드와 value_counts 메서드를 통해 고유값을 확인할 수 있다. 과정은 다음과 같다. 또한 dropna 옵션을 True로 지정하거나 생략하면 NaN값을 제외시킨다는 것을 기억하도록하자.
# unique 메서드를 사용해 고유값 확인하기
print(titanic['Survived'].unique())
# [0 1]
# sort_values 메서드를 사용해 고유값과 그 개수 확인하기
print(titanic['Survived'].value_counts())
# 0 265
# 1 153
# Name: Survived, dtype: int64
데이터를 집계하여 데이터 정보를 간략하게 볼 수 있다. 기본 집계 메서드를 활용하여 볼 수 있는데 종류로는 sum - 합계, mean - 평균, max - 최댓값, min - 최솟값 등의 메서드가 있다. 모든 열에 대해서, 특정 열에 대해서, 특정 열들에 대해서 모두 사용할 수 있다. (사실 특정 열에 대해 집계하는 과정은 기존 데이터프레임으로부터 특정 열 시리즈를 떼어내어 집계 메서드를 사용하는 과정이고 특정 열들에 대해 집계하는 과정도 기존 데이터프레임으로부터 부분 데이터프레임을 떼어내어 집계 메서드를 사용하는 과정이다.) 정보 중 문자열 데이터에 대해 집계함수를 사용하면 예상치 못한 결과가 나올 수 있음에 주의하자.
# 모든 열에 대해 데이터 집계
print(titanic.sum())
# PassengerId 460009
# Survived 153
# dtype: int64
# 특정 열에 대해 데이터 집계
print(titanic['Survived'].sum())
# 153
# 문자열에 대해 데이터 집계
# addr = 'address1'열에 '서울시 구로구 신도림동'이라는 데이터가 7개 저장되어 있는 데이터프레임
addr['address1'].sum()
# 서울시 구로구 신도림동서울시 구로구 신도림동서울시 구로구 신도림동서울시 구로구 신도림동서울시 구로구 신도림동서울시 구로구 신도림동서울시 구로구 신도림동서울시 구로구 신도림동서울시 구로구 신도림동서울시 구로구 신도림동
5. 데이터프레임 조회하기
데이터프레임을 조회하는 방법으로는 크게 특정 열을 조회하는 방법과 조건을 통해 조회하는 방법 2가지가 존재한다.
먼저 특정 열을 조회하는 방법은 또 2가지 방법으로 나눌 수 있는데 DataFrame.Column 혹은 DataFrame['Column']과 같은 명령어를 사용해 1차원 시리즈로 조회하는 방법과 DataFrame[['Column']]과 같은 명령어를 사용해 2차원 데이터프레임으로 조회하는 방법이 있는데 이 방법은 칼럼 대신 칼럼 리스트를 입력하며 데이터를 데이터프레임형식으로 조회했다고 할 수 있다. 과정은 다음과 같다.
# 1차원 시리즈로 조회하기
print(titanic['Survived'])
# 0 0
# 1 0
# 2 0
# 3 1
# 4 0
# ..
# 413 0
# 414 1
# 415 0
# 416 0
# 417 1
# Name: Survived, Length: 418, dtype: int64
# 2차원 데이터프레임으로 조회하기
print(titanic[['PassengerId', 'Survived']])
# PassengerId Survived
# 0 892 0
# 1 893 0
# 2 894 0
# 3 895 1
# 4 896 0
# .. ... ...
# 413 1305 0
# 414 1306 1
# 415 1307 0
# 416 1308 0
# 417 1309 1
#
# [418 rows x 2 columns]
두번째로 조건으로 조회하는 방법이 있다 .loc[]이라는 속성을 사용하여 조회하는 방법인데 loc 내부에는 행 조건 (혹은 행인덱스 = 행 이름)과 열이름(생략 가능)이 들어온다. 이때도 위와 같이 열 이름이 1개라면 시리즈 형태로 리스트형식이라면 데이터프레임 형태로 결과가 나타난다. 과정은 다음과 같다.
print(titanic.loc[titanic['Survived'] == 1, ['PassengerId']])
# PassengerId
# 3 895
# 8 900
# 12 904
# 14 906
# 15 907
# .. ...
# 409 1301
# 410 1302
# 411 1303
# 414 1306
# 417 1309
#
# [153 rows x 1 columns]
and나 or 대신 &와 | 기호를 사용하여 여러 조건을 만족하는 행을 조회할 수 있다. 또한 isin과 between 메서드를 사용해서 조건을 만들 수 있는데 과정은 다음과 같다. 이때 between 메서드는 이상, 이하를 default로 사용함에 주의하자. 즉 between(0, 10)라면 0과 10을 모두 포함하는 사이값을 의미한다.
# 여러 조건을 만족하는 데이터 조회
print(titanic.loc[(titanic['Survived'] == 1) & (titanic['PassengerId'] <= 900), ['Survived', 'PassengerId']])
# Survived PassengerId
# 3 1 895
# 8 1 900
# isin 메서드를 사용하여 조건을 만족하는 데이터 조회
print(titanic.loc[titanic['PassengerId'].isin([800, 900, 1000, 1100, 1200]), ['PassengerId']])
# PassengerId
# 8 900
# 108 1000
# 208 1100
# 308 1200
# between 메서드를 사용하여 조건을 만족하는 데이터 조회
print(titanic.loc[titanic['PassengerId'].between(990, 1000), ['PassengerId']])
# PassengerId
# 98 990
# 99 991
# 100 992
# 101 993
# 102 994
# 103 995
# 104 996
# 105 997
# 106 998
# 107 999
# 108 1000
6. 데이터프레임 집계하기
데이터들의 합(sum), 평균(mean), 최댓값(max), 최소값(min), 개수(count) 등을 기준으로 집계하는 것이 가능하다. 기본적인 문법은 DataFrame.groupby('Column1', as_index=False)['Column2'].집계메서드()이다. 이것은 Column1 별 Column2의 집계를 의미한다. 먼저 하나의 열에 대해 집계하는 과정은 다음과 같다. 아래의 과정은 생존(Survived) 별 승객번호(PassengerId)의 합(sum)을 의미한다.
# 열 하나 집계
print(titanic.groupby('Survived', as_index=False)['PassengerId'].sum())
# Survived PassengerId
# 0 0 292847
# 1 1 167162
또한 여러 열을 집계하는 방법은 다음과 같다. DataFrame.groupby('Column1', as_index=False)['Column List'].집계메서드() 문법은 Column1 별 Column 리스트들의 집계를 의미한다. 과정은 다음과 같다. 즉 아래의 과정은 생존(Survived) 별 승객번호(PassengerId)와 생존여부(Survived)의 합(sum)을 보여준다.
print(titanic.groupby('Survived', as_index=False)[['PassengerId', 'Survived']].sum())
# PassengerId Survived
# 0 292847 0
# 1 167162 153
마지막으로 agg 메서드를 통해 여러 열에 대해 여러 집계를 한번에 수행하는 것이 가능하다. DataFrame.groupby('Column1', as_index=False)['Column List'].agg([집계 메서드 명 List]) 문법은 Column1 별 Column 리스트들의 집계들을 의미한다. 과정은 다음과 같다. 아래의 과정을 통해 생존(Survived) 별 승객번호(PassengerId)와 생존여부(Survived)의 합(sum)과 최댓값(max), 개수(count)를 보여준다.
print(titanic.groupby('Survived', as_index=False)[['PassengerId', 'Survived']].agg(['sum', 'max', 'count']))
# PassengerId Survived
# sum max count sum max count
# Survived
# 0 292847 1308 265 0 0 265
# 1 167162 1309 153 153 1 153
7. 데이터프레임 변경하기
먼저 열 이름을 변경하고 열을 추가하고 삭제하는 방법을 보자. 열 이름을 변경하는 방법은 모든 열 이름을 입력하여 변경하는 방법과 rename 메서드를 이용하여 지정한 열 이름을 변경하는 방법이 있다. HTTP 메서드 중 PUT과 PATCH의 차이같은 느낌이랄까. rename 메서드를 사용할 때 inplace=True 옵션을 주어야 데이터프레임의 열 이름이 실제로 변경된다. 혹은 DataFrame = DataFrame.rename(...)과 같은 방법으로도 실제로 변경시킬 수 있다.
# 모든 열 이름 변경
titanic.columns = ['Pid', 'Surv']
print(titanic)
# Pid Surv
# 0 892 0
# 1 893 0
# 2 894 0
# 3 895 1
# 4 896 0
# .. ... ...
# 413 1305 0
# 414 1306 1
# 415 1307 0
# 416 1308 0
# 417 1309 1
#
# [418 rows x 2 columns]
# 지정한 열 이름 변경
titanic.rename(columns={'Pid': 'PassengerId', 'Surv': 'Survived'}, inplace=True)
print(titanic)
# PassengerId Survived
# 0 892 0
# 1 893 0
# 2 894 0
# 3 895 1
# 4 896 0
# .. ... ...
# 413 1305 0
# 414 1306 1
# 415 1307 0
# 416 1308 0
# 417 1309 1
#
# [418 rows x 2 columns]
열 추가하기는 딕셔너리에 Key-Value 쌍을 저장하듯 추가하면 데이터프레임에 새로운 열이 만들어진다. insert라는 메서드를 이용해 지정한 위치에 열을 추가하는 방법도 다루었지만 실무에서는 열의 물리적인 위치는 신경쓰지 않는다. 열 추가하기는 기본적으로 맨 뒤에 열을 추가하는 방법을 사용한다.
# 맨 뒤에 열 추가하기
titanic['Pid + Surv'] = titanic['PassengerId'] - titanic['Survived']
print(titanic)
# PassengerId Survived Pid + Surv
# 0 892 0 892
# 1 893 0 893
# 2 894 0 894
# 3 895 1 894
# 4 896 0 896
# .. ... ... ...
# 413 1305 0 1305
# 414 1306 1 1305
# 415 1307 0 1307
# 416 1308 0 1308
# 417 1309 1 1308
#
# [418 rows x 3 columns]
# 지정한 위치에 열 추가하기
titanic.insert(1, 'Pid * Surv', titanic['PassengerId'] * titanic['Survived'])
print(titanic)
# PassengerId Pid * Surv Survived Pid + Surv
# 0 892 0 0 892
# 1 893 0 0 893
# 2 894 0 0 894
# 3 895 895 1 894
# 4 896 0 0 896
# .. ... ... ... ...
# 413 1305 0 0 1305
# 414 1306 1306 1 1305
# 415 1307 0 0 1307
# 416 1308 0 0 1308
# 417 1309 1309 1 1308
#
# [418 rows x 4 columns]
열을 삭제하는 방법이다. 데이터프레임에서 열을 삭제하면 되돌리기가 불가능하기 때문에 조심하여 사용해야 한다. drop 메서드를 사용해 열을 삭제한다. axis 옵션의 default 값이 0이기 때문에 drop 메서드는 기본적으로 행을 삭제한다. 따라서 열을 삭제하기 위해서 axis=1로 설정한다. rename 메서드와 같이 drop 메서드를 사용할 때 inplace=True 옵션을 주어야 데이터프레임의 열이 실제로 삭제된다. 과정은 다음과 같다.
titanic.drop(['Pid + Surv', 'Pid * Surv'], axis=1, inplace=True)
print(titanic)
# PassengerId Survived
# 0 892 0
# 1 893 0
# 2 894 0
# 3 895 1
# 4 896 0
# .. ... ...
# 413 1305 0
# 414 1306 1
# 415 1307 0
# 416 1308 0
# 417 1309 1
#
# [418 rows x 2 columns]
다음은 map() 메서드를 살펴보도록 하겠다. 실무에서는 범주형 값을 수치형 값으로 변경할때 사용된다고 한다. 하나의 시리즈에 대해 바뀔 값과 바꿀 값을 지정해두는 방법으로 사용이 가능하다. 과정은 다음과 같다.
# 0 -> False, 1 -> True
titanic['Survived'] = titanic['Survived'].map({0: False, 1: True})
print(titanic)
# PassengerId Survived
# 0 892 False
# 1 893 False
# 2 894 False
# 3 895 True
# 4 896 False
# .. ... ...
# 413 1305 False
# 414 1306 True
# 415 1307 False
# 416 1308 False
# 417 1309 True
#
# [418 rows x 2 columns]
마지막으로 값 크기를 기준으로 지정한 개수의 범위로 나누어 범주 값을 지정하는 cut() 메서드를 살펴보겠다. map() 메서드와 마찬가지로 하나의 시리즈에 대해 적용이 가능하다. 사용 과정은 다음과 같다. 문법은 pd.cut(Series, 범주 개수 or 구간 지정, labels=변경될 이름(범주))이다. 과정은 다음과 같다. 아래 과정에서 구간을 지정하면 (800, 900], (900, 1000], (1000, 1100], ... (1300, 1400] 과 같은 방법으로 구간이 나뉘게 된다. 즉 범위는 리스트의 개수보다 1이 적다. 유의하자.
# 조건에 따라 범위로 나누어 범주 값 지정하기
titanic['PassengerId'] = pd.cut(titanic['PassengerId'], [800, 900, 1000, 1100, 1200, 1300, 1400], labels=[800, 900, 1000, 1100, 1200, 1300])
print(titanic)
# PassengerId Survived
# 0 800 False
# 1 800 False
# 2 800 False
# 3 800 True
# 4 800 False
# .. ... ...
# 413 1300 False
# 414 1300 True
# 415 1300 False
# 416 1300 False
# 417 1300 True
판다스라는 정말 중요한 라이브러리를 배우고 정리해보았다. 인공지능 수업을 들었을 때 데이터를 간략히 요약해서 보여주는 용도 정도로 알고 있었지만 데이터 분석과 요약 전처리 모든 부분에서 사용할 수 있을 것 같다. 강사님께서도 어쩌면 모델링보다 더 중요한 부분이 판다스라고 하셨고 그 부분은 아직 내공이 부족한 나도 어느정도 공감이 되었다. 미니 프로젝트 전까지 판다스를 더 공부해봐야겠다.
크롤링 수업을 진행해주시는 강사님께서는 이 자료를 통해 더 판다스를 공부하길 권하셨다. 꼭 미니 프로젝트 전까지 공부하고 판다스에 내공을 쌓아야겠다.
https://pandas.pydata.org/docs/user_guide/10min.html
10 minutes to pandas — pandas 1.4.3 documentation
Note While standard Python / NumPy expressions for selecting and setting are intuitive and come in handy for interactive work, for production code, we recommend the optimized pandas data access methods, .at, .iat, .loc and .iloc.
pandas.pydata.org
'[KT AIVLE School]' 카테고리의 다른 글
웹크롤링 # 2 Open API - 2022/08/03~2022/08/05 (0) | 2022.08.08 |
---|---|
웹크롤링 # 1 동적 페이지 크롤링 - 2022/08/03~2022/08/05 (0) | 2022.08.07 |
Python 라이브러리 # 1 NumPy - 2022/08/01~2022/08/02 (0) | 2022.08.02 |
프로젝트 관리 도구(GIT) #2 - 2022/07/27 (0) | 2022.07.28 |
프로젝트 관리 도구(GIT) #1 - 2022/07/27 (0) | 2022.07.28 |