날씨에 따른 배달 품목과 주문 건수 분석(1)

최민혁·2023년 11월 8일
0

📌 서울시 날씨별 배달 품목과 주문 건수 분석

데이터 범위: 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

seoul_delivery_df.isnull().sum()

seoul_weather_df

seoul_weather_df.isnull().sum()

  • TMPRT (기온) 13152건 결측치 발생
  • WS (풍속) 13152건 결측치 발생

🖥️ 결측치 처리하기

  • 기온과 풍속의 결측치 들을 평균값으로 대체
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)

  • 기온(TMPRT) : 141건
  • 시간당 강수량(ONEHR_PRCPT_QY_VALUE) : 158건
  • 습도(HD) : 850건
  • 풍속(WS) : 163건

🖥️ 이상치 제거 후 데이터 프레임 저장

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 = seoul_weather_df[['DATE','SIGNGU_CODE','PRCPT_TY_NM','HD','ONEHR_PRCPT_QY_VALUE','TMPRT','WS']]

seoul_weather_df

  • 병합(1) : index 리셋하기
seoul_weather_df = seoul_weather_df.reset_index(drop=True)
seoul_delivery_df = seoul_delivery_df.reset_index(drop=True)
  • 병합 (2) : merge() 함수 사용하기
seoul_wd_df = pd.merge(seoul_weather_df, seoul_delivery_df, left_index=True, right_index=True, how='inner')

seoul_wd_df.head()

📋 DATE_x → DATE , DATE_y 제거

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()

📋 .CSV 파일로 저장하기

seoul_wd_df.to_csv('seoul_wd.csv')

0개의 댓글

관련 채용 정보