Project4. Self Oil Station Price Analysis_제로베이스 강의

JoQuri(조규리)·2023년 12월 19일
0

EDA Project

목록 보기
5/7
post-thumbnail

1. 프로젝트 개요

셀프주요소가 정말 저렴한가요?(서울,휘발유(23.12.19) 기준)

2.데이터 개요

3. 데이터 확보

1. selenium활용

  • 지역선택 시 웹주소가 변하는 게 아닌 그대로 유지. BeutifulSoup을 이용하여 정보 수집을 하기엔 어려움. 웹 브라우저로 접근하지 않으면 안되기에 selenium이용.
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

# 페이지 접근
url = 'https://www.opinet.co.kr/searRgSelect.do'		# 지역별 싼 주유소 URL주소
driver = webdriver.Chrome('../chromedriver.exe')
driver.get(url)
  • 문제 발생
    - 해당 URL(지역별 싼 주유소)로 한번에 접근이 안됨.
    - 메인 페이지(오피넷)로 접속이 되고, 팝업창이 하나 나온다면?
# 팝업창 회면 전환 후 닫아주기
driver.switch_to_window(driver.window_handles[-1])
driver.close()
timpe.sleep(2)
    
# 메인화면 창으로 전환
driver.switch_to_window(driver.window_handles[-1])

# 접근 URL 다시 요청
driver.get(url)
  • 페이지 확인
  • 지역: 시/도 -> '서울' 선택
sido_list_raw = driver.find_element(By.ID,'SIDO_NM0')
# elements로 모든 시/도 
sido_list = sido_list_raw.find_elements(By.TAG_NAME,'option')
# 서울, 서울특별시, 부산, ... 이런 식의 데이터 결과 나옴

sido_names = [sido.get_attribute('value') for sido in sido_list]

['','서울특별시','부산광역시','대구광역시','인천광역시','광주광역시','대전광역시','울산광역시',
'세종특별자치시','경기도','강원특별자치도','충청북도','충청남도','전라북도','전라남도',
'경상북도','경상남도','제주특별자치도']

sido_names = sido_names[1:]   # ' '없애기
# send_keys로 서울 선택
sido_list_raw.send_keys(sido_names[0])
  • 전체 구 선택 및 주요소 내용 엑셀 저장
gu_raw = driver.find_element(By.ID,'SIGUNGU_NM0')        #부모 태그
gu_list = gu_raw.find_elements(By.TAG_NAME,'option')     #자식 태그

gu_names = [gu.get_attribute('value') for gu in gu_list]
gu_names = gu_names[1:]

from tqdm import tqdm

# 전체 구 저장 반복
for gu in tqdm(gu_names):
    gu_raw = driver.find_element(By.ID,'SIGUNGU_NM0')        
    gu_raw.send_keys(gu)					# '시/군/구'에 전체 구 선택
    time.sleep(2)
    										# 엑셀 저장 클릭
    driver.find_element(By.CSS_SELECTOR,'#glopopd_excel').click()
    time.sleep(3)

driver.close()
  • 전체 24개 구의 주유소 엑셀 파일 다운로드 완료

4. 데이터 전처리

import glob

: 파일을 읽어오고 정리하는 모듈

pd.concat() :형식이 동일하고 연달아 붙이기만 하면 될 때

import pandas as pd
from glob import glob

station_files=glob('../data/지역_*.xls')		# 파일 목록 한 번에 가져오기

# 전체 파일 읽어오기
tmp_raw = []

for file_name in station_files:
    tmp = pd.read_excel(file_name, header=2)
    tmp_raw.append(tmp)

# 데이터 병합 concat()
station_raw = pd.concat(tmp_raw)

# 필요정보만 뽑아 DataFrame 
station = pd.DataFrame({
    '상호': station_raw['상호'],
    '주소': station_raw['주소'], 
    '가격': station_raw['휘발유'],
    '셀프여부': station_raw['셀프여부'],
    '상표': station_raw['상표']
})

# 주소를 기준으로 구 뽑아 컬럼 생성
station['구'] = [eachAddress.split()[1] for eachAddress in station['주소']]
station

  • (가정) 문제 발생: 만약 len(구) = 25개가 아닐때?
# 구 컬럼에 '서울특별시'나 '특별시'로 되어있다면?
station.loc[station['구'] == '서울특별시', '구'] = '성동구'
station.loc[station['구'] == '특별시', '구'] = '도봉구'
  • (가정) 문제 발생: 만약 가격type이 연산 불가능한 object라면?
station['가격'] = station['가격'].astype('float')
  • (가정) 문제 발생: 만약 가격 정보가 없는 ('-'형태) 주요소가 있다면?
station[station['가격'] == '-']		#가격 정보 없는 주유소 확인

# 가격정보가 있는 주유소만 사용
station = station[station['가격'] != '-']
station.tail()
  • 문제 발생: 문서들을 병합으로 인해 index가 0~31까지의 반복으로 이루어짐
# 인덱스 재정렬
station.reset_index(inplace=True)
del station['index']

-최종 데이터 전처리

5. 주요 가격 정보 시각화 및 데이터 분석

import matplotlib.pyplot as plt
import seaborn as sns

  • 셀프주유소가 아닌 주유소보다 '대체로 저렴하다!'
  • IQR(전체 데이터의 50%)를 벗어난 outliner(1.5배 벗어난 데이터)가 셀프주유소에 많다
  • 중앙값과 IQR을 보아 셀프주유소가 대체로 더 저렴하다
  • 일반주유소(셀프 아닌)는 중앙값이 1650원이고 주유소 50%의 가격이 1600~1950원지만 선이 긴 것으로 보아 특별히 높은 가격대를 가진 주유소가 있음.

    Boxplot제로베이스 강의

  • 셀프주유소를 비교하면 대체로 비슷한 지표를 가지고 있으나, 길이를 비교해보면 그중 'SK에너지', 'GS칼텍스'가 비싼 편이다.
  • 일반주유소는 'GS칼텍스'가 대체로 비싼 편이다.
  • '알뜰주유소'(자가 포함)를 제외하면, 셀프주유소는 'HD현대오일뱅크'가,
    일반주유소는 'S-OIL'이 저렴한 편이다.

6. 추가 데이터(각 구별 지도 시각화)

import numpy as np
import json
import folium
import warnings         					 # 경고 문구 없애기
warnings.simplefilter(action='ignore', category=FutureWarning)

# 피벗 테이블
gu_data = pd.pivot_table(data=station, index='구', values='가격', aggfunc=np.mean)

# folium.Choropleth
geo_path =
geo_str = json.load(open(geo_path, encoding='utf-8'))
my_map = folium.Map([37.5502, 126.982], zoom_start=10.5, tiles= "CartoDB Positron")
folium.Choropleth(
    geo_data=geo_str,
    data=gu_data,
    columns= [gu_data.index, '가격'],
    key_on ='feature.id',         #data와 map을 합쳐주는 기준
    fill_color = 'PuRd'
).add_to(my_map)
my_map

  • 전체 서울시 구 비교: 용산구 > 종로구 > 중구 > 강남구 순으로 비싼 편이다

새로 배운 코드
from glob import glob

# 구에 '서울특별시'나 '특별시'로 되어있다면?
station.loc[station['구'] == '서울특별시', '구'] = '성동구'
station.loc[station['구'] == '특별시', '구'] = '도봉구'
# 만약 가격 정보가 없는 ('-'형태) 주요소가 있다면?
station[station['가격'] == '-']
# 가격정보가 있는 주유소만 사용
station = station[station['가격'] != '-']
# 주소를 기준으로 구 뽑기
station['구'] = [eachAddress.split()[1] for eachAddress in station['주소']]

“이글은제로베이스데이터취업스쿨의강의자료일부를발췌하여
작성되었습니다.”

0개의 댓글