pandas_01¶
데이터셋 다운로드를 위한 패키지 설치¶
#!pdm add opendata-kr
데이터 다운로드¶
from opendata import dataset
dataset.download('서울시대중교통')
======= 다운로드 시작 =======
data/서울시대중교통/seoul_transportation.xlsx
======= 다운로드 완료 =======
파일 읽기¶
pandas는 아래와 같은 형태의 파일을 읽어 올 수 있음.
excel:
pd.read_excel()
csv:
pd.read_csv()
pickle:
pd.read_pickle()
json:
pd.read_json()
엑셀 읽기 위해 openpyxl 라이브러리 설치:
pdm add openpyxl
엑셀 읽기:
pd.read_excel('경로/파일명', sheet_name='', engine='openpyxl')
Tip
sheet_name 입력하지 않을 경우 전체 시트를 가져옴
#!pdm add openpyxl
import pandas as pd
pd.options.display.float_format = '{:.2f}'.format
df = pd.read_excel('./data/서울시대중교통/seoul_transportation.xlsx', engine='openpyxl')
데이터 처리¶
info:
df.info()
index:
df.index
columns:
df.columns
sort:
df.sort_values(by=['컬럼명'], ascending=True/False)
ascending=False 이면 내림차순 정렬
slicing
loc: 행,열을 기준으로 데이터 값 추출
df.loc[:5, '컬럼명']
iloc: 인덱스를 기준으로 슬라이싱
df.iloc[1, 3]
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 601 entries, 0 to 600
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 대중교통구분 601 non-null object
1 노선명 601 non-null object
2 년월 601 non-null int64
3 승차총승객수 601 non-null int64
dtypes: int64(2), object(2)
memory usage: 18.9+ KB
Dtype: Object(문자형을 포함한 객체 타입), int64(정수형), float64(실수형)
RangeIdex: 601 -> 숫자형태로 인덱스가 지정되어 있으며 전체 데이터 개수 601개임
df.columns
Index(['대중교통구분', '노선명', '년월', '승차총승객수'], dtype='object')
컬럼은 4개 ‘대중교통구분’, ‘노선명’, ‘년월’, ‘승차총승객수’
Tip
* df.columns, df.value_counts()
* ()가 있는 것은 데이터 프레임의 함수를 호출하는 것이고, ()가 없는 것은 속성값을 가져오는 것임
df.sort_values(by=['승차총승객수'], ascending=False).head()
대중교통구분 | 노선명 | 년월 | 승차총승객수 | |
---|---|---|---|---|
37 | 지하철 | 2호선 | 201905 | 49356486 |
23 | 지하철 | 2호선 | 201803 | 49033111 |
30 | 지하철 | 2호선 | 201810 | 48343358 |
31 | 지하철 | 2호선 | 201811 | 48332253 |
20 | 지하철 | 2호선 | 201712 | 48288516 |
승차총승객수로 내림차순 정렬, 가장 많은 승객수는 2019년 5월 2호선
df.loc[:5, ['대중교통구분', '노선명']]
대중교통구분 | 노선명 | |
---|---|---|
0 | 지하철 | 1호선 |
1 | 지하철 | 1호선 |
2 | 지하철 | 1호선 |
3 | 지하철 | 1호선 |
4 | 지하철 | 1호선 |
5 | 지하철 | 1호선 |
df.loc[행, 열]
행 ‘start:end;step’ 형태로 지정 :10은 0부터 10번째 행을 가져오라는 의미
열 ‘컬럼명’을 명시하거나 ‘컬럼명’:’컬럼명’으로 지정
통계¶
df.describe()
데이터프레임의 주요 통계량 정보 조회
df.count()
,df.mean()
,df.max()
,df.quantile()
df.agg(['min', 'max', 'count'])
개별 통계 조회가 아닌 필요한 내용을 한번에 조회하는 방법
df.unique()
데이터 중 유니크 개수
df.describe()
년월 | 승차총승객수 | |
---|---|---|
count | 601.00 | 601.00 |
mean | 201822.42 | 7542216.74 |
std | 56.30 | 9225438.09 |
min | 201711.00 | 343785.00 |
25% | 201803.00 | 1403115.00 |
50% | 201808.00 | 3537142.00 |
75% | 201901.00 | 10346038.00 |
max | 201905.00 | 49356486.00 |
df['승차총승객수'].agg(['min', 'max', 'quantile'])
min 343785.00
max 49356486.00
quantile 3537142.00
Name: 승차총승객수, dtype: float64
‘서울시대중교통’ 데이터셋에는 ‘승차총승객수’만 통계량 산출이 가능한 상황
df[‘승차총승객수’] 의미는 ‘승차총승객수’ 컬럼만 가져온다는 의미임
df['노선명'].unique()
array(['1호선', '2호선', '3호선', '4호선', '경부선', '경인선', '경원선', '안산선', '과천선',
'분당선', '일산선', '중앙선', '장항선', '경의선', '경춘선', '수인선', '경강선', '서해선',
'5호선', '6호선', '7호선', '8호선', '인천1호선', '인천2호선', '9호선', '공항철도 1호선',
'신분당선', '9호선2~3단계', '용인에버라인', '의정부경전철', '경기철도', '우이신설선'],
dtype=object)
df.unique()
하면 error 발생unique() 함수는 특정 컬럼별 조회
df.nunique() # 전체 컬럼별 유니크한 값 개수 조회
대중교통구분 1
노선명 32
년월 19
승차총승객수 601
dtype: int64
data visualization with bokeh¶
bokeh는 python data visualization tool 중 하나
다른 툴보다 자유도가 높은 것이 장점이나, seaborn과 같이 쉽지 않은 것이 단점
bokeh library import¶
bokeh 설치
pdm add bokeh
library import
ColumnDataSource: bokeh는 dictionary 형태의 데이터를 이용하여 차트를 생성함.
dataframe 형태의 데이터를 dictionary형으로 전환해 주어야 함.
df.to_dict('list')
함수 이용
출력
브라우저, html, notebook 등 다양한 형태로 차트를 출력함
jupyter notebook을 출력 매체로 사용할 경우 bokeh.io import 및 output_notebook() 호출 필요
df 데이터 전처리¶
chart를 위해 월 평균 이용 고객수 산출하여 데이터 정제
df[‘년월’] 데이터는 ‘201801’ 6자리 문자열로 되어 있기 때문에 이를 datatime 형식으로 변경
pd.to_datetime()
함수 이용
new = df.groupby(['년월'])['승차총승객수'].mean().reset_index()
new['년월'] = pd.to_datetime(df['년월'],format='%Y%m')
new.dtypes
년월 datetime64[ns]
승차총승객수 float64
dtype: object
bokeh chart¶
new dataset을 dictionay 형태로 데이터 전환
df.to_dict('list')
함수 이용
data = new.to_dict('list')
source = ColumnDataSource(data)
p = figure(title='월 평균 지하철 이용 승객수',
x_axis_label='년월',
y_axis_label='승차총승객수',
x_axis_type='datetime',
width = 700,
height = 300
)
p.line(x='년월', y='승차총승객수', source=source)
show(p)