데이터 범위: 2020-01월 ~ 2020-10월 까지 서울 날씨 및 주문 데이터
데이터 출처 : KT 통신 빅데이터 플랫폼(https://bdp.kt.co.kr/invoke/SOKBP0000/?ver=3.0)
서울시 배달 주문 데이터 중 날씨에 따라 배달 주문 건수 차이와 날씨별 주요 배달 품목을 분석
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns
delivery_df = pd.read_csv('업종_목적지별_배달_주문건수.csv')
weather_df = pd.read_csv('날씨정보.csv',low_memory=False)
delivery_df.head()
weather_df.head()
delivery_df
- DE (date) : 주문 날짜(yyyy-mm-dd)
- HRLY_TIME (varchar) : 주문 시간대별 구분 (HH)
- DLVR_STORE_INDUTY_NM (varchar) : 배달상점 업종명(카테고리)
- DESTINATION_BRTC_NM (varchar) : 배달 목적지 주소 광역시도명
- DESTINATION_SIGUNGU_NM (varchar) : 배달 목적지 주소 시군구명
- ORDER_CASCNT (int) : 주문 건수
weather_df
- SN(int) : 순번
- SIGNGU_CODE(varchar) : 시군구 코드
- BRTC_NM (varchar) : 광역시도명
- SIGNGU_NM (varchar) : 시군구명
- OTHBC_DE (varchar) : 공개연월일(YYYYmmdd)
- OTHBC_TIME (varchar) : 공개시간(HHMM)
- PRCPT_TY_NM (varchar) : 강수타입
- HD (float) : 습도(%)
- ONEHR_PRCPT_QY_VALUE (float) : 1시간 강수량(㎜)
- TMPRT (float) : 기온(℃)
- WS (float) : 풍속(m/s)
- WIND_IN_TY_NM (varchar) 바람강도 유형명(약,약간강,강,매우강)
- EAST_WST_WIND_TY_NM (varchar) : 동쪽 서쪽 바람 유형명(east/west)
- WD_VALUE (int) : 풍향값(0~359)
- WD_VALUE (varchar) : 풍향카테고리명(풍향값에 따른 16방위)
delevery_df.info()
weather_df.info()
weather_df['HD'] = weather_df['HD'].astype('float')
weather_df['ONEHR_PRCPT_QY_VALUE'] = weather_df['ONEHR_PRCPT_QY_VALUE'].replace('\\N', float('nan')).astype('float')
weather_df['TMPRT'] = weather_df['TMPRT'].replace('\\N', float('nan')).astype('float')
weather_df['WS'] = weather_df['WS'].replace('\\N',float('nan')).astype('float')
seoul_delivery_df = delivery_df[delivery_df['DESTINATION_BRTC_NM'] == '서울특별시']
seoul_delivery_df.head()
seoul_weather_df = weather_df[weather_df['BRTC_NM']=='서울특별시']
seoul_weather_df.head()
seoul_delivery_df= seoul_delivery_df.rename(columns={'DE':'DATE'})
seoul_weather_df = seoul_weather_df.rename(columns={'OTHBC_DE':'DATE'})
2020-01-01 ~ 2020-10-31 까지로 설정
seoul_delivery_df['DATE'] = pd.to_datetime(seoul_delivery_df['DATE'])
start_date = pd.to_datetime('2020-01-01')
end_date = pd.to_datetime('2020-10-31')
seoul_delivery_df = seoul_delivery_df[
(seoul_delivery_df['DATE'] >= start_date) &
(seoul_delivery_df['DATE'] <= end_date)
] ### 주문 데이터
seoul_weather_df['DATE'] = pd.to_datetime(seoul_weather_df['DATE'], format='%Y%m%d')
start_date = pd.to_datetime('2020-01-01')
end_date = pd.to_datetime('2020-10-31')
seoul_weather_df = seoul_weather_df[
(seoul_weather_df['DATE'] >= start_date) &
(seoul_weather_df['DATE'] <= end_date)
] ### 날씨 데이터
seoul_delivery_df.isnull().sum()
seoul_weather_df.isnull().sum()
seoul_weather_df['TMPRT'] = seoul_weather_df['TMPRT'].fillna(seoul_weather_df['TMPRT'].mean()) ## 기온
seoul_weather_df['WS'] = seoul_weather_df['WS'].fillna(seoul_weather_df['WS'].mean()) ## 풍속
배달 주문 건수의 대한 날씨 데이터로 기온 , 강수량 , 습도 , 풍속에 대한 이상치를 조회
# IQR을 사용한 기온 이상치 조회
q1_tmprt = seoul_weather_df['TMPRT'].quantile(0.25)
q3_tmprt = seoul_weather_df['TMPRT'].quantile(0.75)
iqr_tmprt = q3_tmprt - q1_tmprt
threshold_iqr_tmprt = 1.5 # 이상치 판단 기준값 (일반적으로 1.5를 사용)
lower_bound_tmprt = q1_tmprt - threshold_iqr_tmprt * iqr_tmprt
upper_bound_tmprt = q3_tmprt + threshold_iqr_tmprt * iqr_tmprt
outliers_tmprt_iqr = seoul_weather_df[(seoul_weather_df['TMPRT'] < lower_bound_tmprt) | (seoul_weather_df['TMPRT'] > upper_bound_tmprt)]
# 결과 출력
print("기온(TMPRT) IQR 이상치:")
print(outliers_tmprt_iqr)
# 이상치 판단 기준값
threshold_iqr_onehr_rain = 1.5
# IQR 계산
q1_onehr_rain = seoul_weather_df['ONEHR_PRCPT_QY_VALUE'].quantile(0.25)
q3_onehr_rain = seoul_weather_df['ONEHR_PRCPT_QY_VALUE'].quantile(0.75)
iqr_onehr_rain = q3_onehr_rain - q1_onehr_rain
# 이상치 판단 범위 설정 (음수만 고려)
lower_bound_onehr_rain = q1_onehr_rain - threshold_iqr_onehr_rain * iqr_onehr_rain
# 음수인 경우만 이상치로 간주
outliers_onehr_rain_iqr = seoul_weather_df[seoul_weather_df['ONEHR_PRCPT_QY_VALUE'] < lower_bound_onehr_rain]
# 결과 출력
print("시간당 강수량(ONEHR_PRCPT_QY_VALUE) 이상치:")
print(outliers_onehr_rain_iqr)
# IQR을 사용한 습도 이상치 조회
q1_hd = seoul_weather_df['HD'].quantile(0.25)
q3_hd = seoul_weather_df['HD'].quantile(0.75)
iqr_hd = q3_hd - q1_hd
threshold_iqr_hd = 1 # 이상치 판단 기준값
lower_bound_hd = q1_hd - threshold_iqr_hd * iqr_hd
upper_bound_hd = q3_hd + threshold_iqr_hd * iqr_hd
outliers_hd_iqr = seoul_weather_df[(seoul_weather_df['HD'] < lower_bound_hd) | (seoul_weather_df['HD'] > upper_bound_hd)]
# 결과 출력
print("습도(HD)의 IQR 이상치:")
print(outliers_hd_iqr)
threshold_iqr_ws = 1 # 이상치 판단 기준값
q1_ws = seoul_weather_df['WS'].quantile(0.25)
q3_ws = seoul_weather_df['WS'].quantile(0.75)
iqr_ws = q3_ws - q1_ws
# 이상치 판단 범위 설정
lower_bound_ws = q1_ws - threshold_iqr_ws * iqr_ws
# 음수인 경우만 이상치로 간주
outliers_ws_iqr = seoul_weather_df[seoul_weather_df['WS'] < lower_bound_ws]
# 결과 출력
print("풍속(WS)의 이상치:")
print(outliers_ws_iqr)
seoul_weather_df = seoul_weather_df[~((seoul_weather_df['TMPRT'] < q1_tmprt - threshold_iqr_tmprt * iqr_tmprt) | (seoul_weather_df['TMPRT'] > q3_tmprt + threshold_iqr_tmprt * iqr_tmprt))]
seoul_weather_df = seoul_weather_df[~((seoul_weather_df['ONEHR_PRCPT_QY_VALUE'] < q1_onehr_rain - threshold_iqr_onehr_rain * iqr_onehr_rain) | (seoul_weather_df['ONEHR_PRCPT_QY_VALUE'] > q3_onehr_rain+ threshold_iqr_onehr_rain * iqr_onehr_rain))]
seoul_weather_df = seoul_weather_df[~((seoul_weather_df['HD'] < q1_hd - threshold_iqr_hd * iqr_hd) | (seoul_weather_df['HD'] > q3_hd + threshold_iqr_hd * iqr_hd))]
seoul_weather_df = seoul_weather_df[~((seoul_weather_df['WS'] < q1_ws - threshold_iqr_ws * iqr_ws) | (seoul_weather_df['WS'] > q3_ws + threshold_iqr_ws * iqr_ws))]
print(seoul_weather_df)
weather_duplicate = seoul_weather_df[seoul_weather_df.duplicated(keep=False)]
print(weather_duplicate) ### 날씨 데이터 프레임
delivery_duplicate = seoul_delivery_df[seoul_delivery_df.duplicated(keep=False)]
print(delivery_duplicate) ### 주문 데이터 프레임
각 데이터 프레임에서는 중복된 데이터가 발견되지 않음.
seoul_weather_df 와 seoul_delivery_df 병합
seoul_weather_df = seoul_weather_df[['DATE','SIGNGU_CODE','PRCPT_TY_NM','HD','ONEHR_PRCPT_QY_VALUE','TMPRT','WS']]
seoul_weather_df
seoul_weather_df = seoul_weather_df.reset_index(drop=True)
seoul_delivery_df = seoul_delivery_df.reset_index(drop=True)
seoul_wd_df = pd.merge(seoul_weather_df, seoul_delivery_df, left_index=True, right_index=True, how='inner')
seoul_wd_df.head()
seoul_wd_df.rename(columns={'DATE_x':'DATE'},inplace=True)
seoul_wd_df = seoul_wd_df.drop('DATE_y',axis=1)
seoul_wd_df.head()
seoul_wd_df.to_csv('seoul_wd.csv')