PYTHON DATA 시각화 – PANDAS #1
pandas 를 사용한 기본 도식화¶
pandas 는 많은 절차를 자동화해 도식화를 매우 쉽게 해준다. 도식화는 내부적으로 Matplotlib에 의해 처리된다.
- 그릴 수 있는 도면 -- 선 -- 막대 -- 상자 -- 산포도 -- 커널 밀도 추정(KDE, Kernel Density Estimates) -- 히스토그램
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.DataFrame(index=['Atiya','Abbas','Cornelia','Stephanie','Monte'],
data={'Apples':[20,10,40,20,50],
'Oranges':[35,40,25,19,33]})
df
1. bar plot 그리기¶
color=['.2','.7']
ax = df.plot.bar(color=color,figsize=(16,4))
ax.get_figure().savefig('c13-pdemo-bar1.png')
2. KDE plot¶
인덱스를 무시하고 열 이름을 x축을 따라 사용하고 열 값을 y축을 따라 확률 밀도를 계산하는 데 사용한다.
ax = df.plot.kde(color=color,figsize=(16,4))
ax.get_figure().savefig('c13-pdemo-kde1.png')
3. line, scatter, bar plot¶
하나의 figure 에 line, scatter, bar 차트 그리기
fig, (ax1, ax2, ax3) = plt.subplots(1,3,figsize=(16,4))
fig.suptitle("†wo Variable Plots", size=20, y=1.02)
df.plot.line(color=color, ax=ax1, title='Line Plot')
df.plot.scatter(x='Apples', y='Oranges', ax=ax2, title='Scatter Plot')
df.plot.bar(color=color, ax=ax3, title='Bar Plot')
fig.savefig('c13-pdemo-scat.png')
4. KDE, 상자그림, 히스토그램 plot¶
하나의 figure 에 KDE, 상자그림, 히스토그램 넣기
fig, (ax1, ax2, ax3) = plt.subplots(1,3,figsize=(16,4))
fig.suptitle("One Variable Plots", size=20, y=1.02)
df.plot.kde(color=color, ax=ax1, title='KDE plot')
df.plot.box(ax=ax2, title='Boxplot')
df.plot.hist(color=color, ax=ax3, title='Histogram')
fig.savefig('c13-pdemo-kde2.png')
5. 열 지정 후 시각화¶
x 나 y 값에 사용하려는 정확한 열을 지정을 하거나 데이터 정렬 후 시각화 한다.
fig, (ax1, ax2, ax3) = plt.subplots(1,3, figsize=(16,4))
df.sort_values('Apples').plot.line(x='Apples', y='Oranges', ax=ax1)
df.plot.bar(x='Apples', y='Oranges', ax=ax2)
df.plot.kde(x='Apples', ax=ax3)
6. flights 데이터 시각화¶
우회, 취소, 연착, 정시 운행된 항공편을 계산 데이터를 보면 DIVERTED : 후회 CANCELLED : 취소 DELAY : 예정보다 15분을 넘게 도착(ARR_DELAY)
flights = pd.read_csv('data/flights.csv')
flights
DELAYED, ON_TIME column 을 생성해준다
cols = ['DIVERTED','CANCELLED', 'DELAYED']
(
flights
.assign(DELAYED=flights['ARR_DELAY'].ge(15).astype(int),
ON_TIME=lambda df_: 1 - df_[cols].any(axis=1))
.select_dtypes(int)
.sum()
)
fig, ax_array = plt.subplots(2, 3, figsize=(18,8))
(ax1, ax2, ax3), (ax4, ax5, ax6) = ax_array
fig.suptitle('2015 US Flights - Univariate Summary', size=20)
ac = flights['AIRLINE'].value_counts()
ac.plot.barh(ax=ax1, title='Airline')
(
flights['ORG_AIR'].value_counts().plot.bar(ax=ax2, rot=0, title='Origin City')
)
(
flights['DEST_AIR'].value_counts().head(10).plot.bar(ax=ax3, rot=0, title='Destination City')
)
(
flights.assign(DELAYED=flights['ARR_DELAY'].ge(15).astype(int),
ON_TIME=lambda df_: 1 - df_[cols].any(axis=1))
[['DIVERTED','CANCELLED','DELAYED','ON_TIME']].sum()
.plot.bar(ax=ax4, rot=0, log=True, title='Flight Status')
)
flights['DIST'].plot.kde(ax=ax5, xlim=(0,3000), title='Distance KDE')
flights['ARR_DELAY'].plot.hist(ax=ax6, title='Arrival Delay', range=(0,200))
fig.savefig('c13-uni1.png')
6-1 flights 를 주별 데이데 시각화(resample 함수)¶
flights 데이터는 MONTH, DAY 값이 정의 되어 있다. SCHED_DEP의 컬럼을 이용하여 HOUR, MINUTE 의 컬럼을 정의 할 수 있다.
df_date = (
flights[['MONTH','DAY']]
.assign(YEAR=2015,
HOUR=flights['SCHED_DEP'] // 100,
MINUTE=flights['SCHED_DEP'] % 100)
)
flights_dep = pd.to_datetime(df_date)
flights.index = flights_dep
fc = flights.resample('W').size()
fc.plot.line(figsize=(12,3), title='Flights per Week', grid=True)
fig.savefig('c13-ts1.png')
6-2 보간법을 사용해 누락된 데이터 처리¶
10월에 대한 데이터가 누락 되었다. 첫 주와 마지막 주도 평소보다 낮은데, 7일이 꽉 찬 완전한 주가 아닐 수 있기 때문일 수도 있다.
600편 미만의 비행이 있는 주는 결측치로 만들고, 보간법을 사용해 누락된 데이터를 채운다.
def interp_lt_n(df_, n=600):
return (df_
.where(df_ > n)
.interpolate(limit_direction='both')
)
fig, ax = plt.subplots(figsize=(16,4))
data = (flights
.resample('W')
.size())
(data
.pipe(interp_lt_n)
.iloc[1:-1]
.plot.line(color='black', ax=ax)
)
mask = data < 600
(data
.pipe(interp_lt_n)
[mask]
.plot.line(color='.8', linewidth=10)
)
ax.annotate(xy=(.8, .55), xytext=(.8, .77), xycoords='axes fraction', s='missing data', ha='center', size=20, arrowprops=dict())
ax.set_title('Flights per Week (Interpolated Missing Data)')
fig.savefig('c13-ts2.png')
6-3 평균 항로가 가장 긴 공항¶
- 인입 항공편의 평균 항로가 가장 긴 공항
- 최소 100개의 전체 항공편
fig, ax = plt.subplots(figsize=(16,4))
(flights
.groupby('DEST_AIR')
['DIST']
.agg(['mean','count'])
.query('count > 100')
.sort_values('mean')
.tail(10)
.plot.bar(y='mean', rot=0, legend=False, ax=ax, title='Average Distance per Destination')
)
fig.savefig('c13-var1.png')
6-4 산포도 그리기¶
2,000 마일 미만의 모든 비행에서 거리와 비행시간 사이의 산포도 그리기
fig, ax = plt.subplots(figsize=(8,6))
(flights
.reset_index(drop=True)
[['DIST','AIR_TIME']]
.query('DIST <= 2000')
.dropna()
.plot.scatter(x='DIST',y='AIR_TIME',ax=ax, alpha=.1, s=1)
)
fig.savefig('c13-scat1.png')
flights[['DIST','AIR_TIME']].corr()
6-5 cut 함수를 이용하여 그룹 으로 만들기¶
거리와 운행 시간 사이에 선형 관계가 존재하지만 마일 수가 중가함에 따라 분산도 증가하는것이 보인다. cut 함수를 사용해 비행 거리를 8개의 그루으로 만든다.
(flights
.reset_index(drop=True)
[['DIST','AIR_TIME']]
.query('DIST<=2000')
.dropna()
.pipe(lambda df_:pd.cut(df_.DIST, bins=range(0,2001, 250)))
.value_counts()
.sort_index()
)
6-6 각 그룹 내 평균 운항 시간에서 벗어난 표준편차 구하기¶
zscore = lambda x: (x-x.mean()) / x.std()
short = (flights
[['DIST','AIR_TIME']]
.query('DIST<=2000')
.dropna()
.reset_index(drop=True)
.assign(BIN=lambda df_:pd.cut(df_.DIST,bins=range(0,2001,250)))
)
scores = (short
.groupby('BIN')
['AIR_TIME']
.transform(zscore)
)
(short.assign(SCORE=scores))
6-7 상자그림을 통하여 이상치 발견¶
fig, ax = plt.subplots(figsize=(10,6))
(short.assign(SCORE=scores).pivot(columns='BIN')['SCORE'].plot.box(ax=ax))
ax.set_title('Z-Score for Distance Groups')
fig.savefig('c13-box2.png')
6-8 6표준편차 보다 큰 데이터 확인¶
mask = (short.assign(SCORE=scores).pipe(lambda df_:df_.SCORE.abs()>6))
outliers = (flights
[['DIST','AIR_TIME']]
.query('DIST <= 2000')
.dropna()
.reset_index(drop=True)
[mask]
.assign(PLOT_NUM=lambda df_:range(1, len(df_)+1))
)
outliers
6-9 scatter plot 에서 이상치와 같이 그리기¶
fig, ax = plt.subplots(figsize=(8,6))
(short
.assign(SCORE=scores)
.plot.scatter(x='DIST',y='AIR_TIME', alpha=.1, s=1, ax=ax, table=outliers)
)
outliers.plot.scatter(x='DIST',y='AIR_TIME', s=25, ax=ax, grid=True)
outs = outliers[['AIR_TIME','DIST','PLOT_NUM']]
for t, d, n in outs.itertuples(index=False):
ax.text(d+5, t+5, str(n))
plt.setp(ax.get_xticklabels(), y=.1)
plt.setp(ax.get_xticklines(), visible=False)
ax.set_xlabel('')
ax.set_title('Flight Time vs Distance with Outliers')
fig.savefig('c13-scat3.png', dpi=300, bbox_inches='tight')