Python 파이썬

파이썬 단변량 분석(EDA)

now!_::D___GOoooo___ 2023. 3. 7. 22:33


이전 포스팅에서는 폴더 내 데이터를 한번에 불러오고 병합하는 방법을 몰라서 2022년 2월 데이터만 사용했었음... 

 

이번 포스팅에서는 2021년 1월 ~ 2021년 12월 대기정보 데이터 사용

 

** 데이터 다운로드 

에어코리아 → 통계정보 → 최종확정 측정자료 조회 → 확정자료 다운로드 → 2021년 데이터 다운로드

https://www.airkorea.or.kr/web/last_amb_hour_data?pMENU_NO=123 

 

1. 라이브러리

# 라이브러리
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# warnings 무시
import warnings
warnings.filterwarnings('ignore')

# 폰트설정
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False

# 그래프 선명
%config InlineBackend.figure_format = 'retina'

 

2. 데이터 불러오기

# 폴더내 파일명 불러오고 데이터 병합 - glob()
import pandas as pd
from glob import glob
file_names = glob("경로/2021*.xlsx")  # 2021*.xlsx : 2021문자로 시작하는 xlsx 파일
total = pd.DataFrame()

for file_name in file_names:
    temp = pd.read_excel(file_name)
    total = pd.concat([total, temp])

=> 데이터가 커서 불러오는 것만 10분 정도 소요 됨(코드는 길어지지만 하나씩 불러오는게 더 빠른 것 같음......) 

** glob은 파일명을 불러온 후, for()문을 사용하여 짧은 코드로 데이터 병합을 할 수 있다.

 

3. 인천시 내 측정소명 기준인  air 데이터프레임 생성

# 인천 데이터를 뽑아서 incheon_air 데이터프레임 생성
incheon_air = total[total['지역'].str.contains('인천')]

# air 데이터프레임으로 복사
air = incheon_air.copy()

# 불필요한 컬럼 삭제
drop_col = ['Unnamed: 0', '지역', '망', '측정소코드', '주소']
air.drop(drop_col, axis=1, inplace=True)

# 인덱스 초기화
air.reset_index(drop=True, inplace=True)

air.head()

 

4. 측정일시 

1) datetime 변환 - 파이썬 int타입_datetime타입으로 변환 (tistory.com) 참고

2) 슬라이싱으로 컬럼 생성 - 여기서는 이 방법으로 진행

 

# 측정일시 컬럼 문자열로 변환
air['측정일시'] = air['측정일시'].astype('str')

# 측정날짜 컬럼 데이터 중 7번째까지 측정일시, 8번째부터 끝까지는 측정시간 컬럼 생성
air['측정날짜'] = air['측정일시'].str[:8]
air['측정시간'] = air['측정일시'].str[8:]

# 측정날짜 컬럼 datetime타입으로 변환
air['측정날짜'] = pd.to_datetime(air['측정날짜'])

display(air.head())
air.info()

=> datetime 타입인 측정날짜 컬럼과 object인 측정시간 컬럼 생성함.

 

 

5. 인천광역시 측정날짜별 데이터

col = ['SO2', 'CO', 'O3', 'NO2', 'PM10', 'PM25']
air_incheon = air.groupby('측정날짜', as_index=False)[col].mean()

=>  측정날짜를 기준으로 각 측정소의 대기정보 평균으로 인천시 대기정보 평균 데이터프레임 생성

 

- 데이터 확인

air_incheon.head()

air_incheon.info()

결측값 없고 데이터도 잘 가져왔다.

데이터 준비하는 것만 오래 걸렸다... (측정소별 하려다 너무 길어질 것 같아서 인천으로 그룹화 해버림...)

 

- 기초통계량 : describe()

# 기초통계량
air_incheon.describe()

=> 데이터 수, 평균, 표준편차, 최솟값, 1사분위수, 2사분위수, 3사분위수, 최댓값 순서로 정보를 알 수 있음.

 

 

- 히스토그램 : plt.hist()

pm25_hist = plt.hist(air_incheon['PM25'], bins=10, edgecolor='gray')
plt.xlabel('PM25')
plt.ylabel('Count')
plt.show()

print(pm25_hist)
print('-'*50)
print('구간값 : ', pm25_hist[1])
print('빈도수 : ', pm25_hist[0])

=> 각 구간값 별 빈도수 출력해서 확인

=> PM25는 30아래로 분포가 몰려 있음

 

 

- 밀도함수 그래프 : kdeplot()

sns.kdeplot(air_incheon['PM25'])
plt.show()

=> 많은 데이터가 0~50에 분포한다.

 

- 히스토그램+밀도함수그래프 : histplot(kde=True)

# 히스토그램과 밀도함수그래프 같이 그리기
sns.histplot(incheon_air['PM25'], bins=10, kde=True)
plt.show()

=> 히스토그램과 밀도함수 그래프를 함께 그림

 

 

- 박스플롯 : boxplot

# 박스플롯
sns.boxplot(x=air_incheon['PM25'])
plt.grid()
plt.show()

=> 최솟값, 1사분위수, 2사분위수(중위수), 3사분위수, 최댓값 확인할 수 있다.

=> 박스플롯으로 이상치 확인가능

 

 

- 선그래프 : plot()

plt.figure(figsize=(10,10))

plt.subplot(4,1,1)
plt.plot(air_incheon['측정날짜'], air_incheon['PM10'], label='PM10')
plt.plot(air_incheon['측정날짜'], air_incheon['PM25'], label='PM25')
plt.legend()

plt.subplot(4,1,2)
plt.plot(air_incheon['측정날짜'], air_incheon['CO'], label='CO')
plt.legend()

plt.subplot(4,1,3)
plt.plot(air_incheon['측정날짜'], air_incheon['O3'], label='O3')
plt.plot(air_incheon['측정날짜'], air_incheon['NO2'], label='NO2')
plt.legend()

plt.subplot(4,1,4)
plt.plot(air_incheon['측정날짜'], air_incheon['SO2'], label='SO2')
plt.legend()

plt.show()

 

=> 측정날짜별 대기측정정보를  선그래프로 확인

=> 3월, 5월에 PM10 수치가 급격하게 높아진 날짜가 있음. 확인할 필요 있음

=> CO는 겨울에 높은편임

=> O3는 여름에 높아지는 것을 볼 수 있음. NO2는 겨울에 다른 계절보다 높은 것을 확인할 수 있음

=> 4월 SO2 수치가 급격하게 높아졌고, 10월 이후 높아지는 추세를 보임

 

6. PM25 위험도에 따른 기준으로 범주형으로 변환

** 참고 : 환경부 - 미세먼지(PM2.5) 환경기준 미국 일본 수준으로 강화 (me.go.kr)

 

0~15:좋음, ~35:보통, ~75:나쁨, ~∞:매우나쁨

pm25_bin = [0,15,35,75,np.inf]
pm25_label = ['좋음', '보통', '나쁨', '매우나쁨']

air_incheon['pm25_standard'] = pd.cut(air_incheon['PM25'], bins=pm25_bin, labels=pm25_label)
air_incheon['pm25_standard'].value_counts()

 

- 막대그래프 : countplot() 

sns.countplot(x='pm25_standard', data=air_incheon)
plt.show()

 

- 파이차트 : pie()

temp = air_incheon['pm25_standard'].value_counts()

plt.pie(temp.values, labels = temp.index, autopct = '%.2f%%')
plt.show()

 

# 파이차트 옵션
plt.pie(temp.values, labels = temp.index, autopct = '%.2f%%', 
        startangle=90, counterclock=False, 
        explode = [0.05, 0.05, 0.05, 0.05], shadow=True)
plt.show()

 

365일 중에 [보통 171일, 좋음 155일, 나쁨 34일, 매우나쁨 5일]임을 확인할 수 있다.

 

 

- 2021년에는 초미세먼지 PM25가 좋음과 보통인 날이 90%이상이다.