-
서울시 프랜차이즈 햄버거(버거킹/맥도날드/맘스터치/롯데리아) 분석 & 시각화 with Python, PydeckData Analysis/LifeStyles 2021. 3. 6. 13:48
이번 포스팅에서는 서울시 내 위치한 프랜차이즈 버거(버거킹, 롯데리아, 맥도날드, 맘스터치) 위치 데이터를 카카오 지도 API를 활용해서 가져온 다음 해당 데이터를 갖고 간단한 분석과 시각화를 해보도록 하겠다.
Data Source: Kakao 지도 Api
버거 브랜드 홈페이지에서 가져온 데이타가 아닌 카카오 API를 활용한 데이터이다 보니 100% 정확한 수치는 아니다. 서울시 내 버거 지점 수에서는 롯데리아>맘스터치>버거킹>맥도날드 순으로 나타났다.
from bs4 import BeautifulSoup as bs import pandas as pd import requests link='https://www.seoul.go.kr/seoul/autonomy.do' re=requests.get(link) obj=bs(re.content,'html.parser') gu=[] for s in obj.find_all('li',{'class':'tabcont'}): gu.append(s.select_one('strong').get_text()) api='~~~' def burger(key,x): data=[] for v in gu: query=v+x for i in range(1,10): url = f'''https://dapi.kakao.com/v2/local/search/keyword?query={query}&page={i}&size=15''' headers = { "Authorization": f"KakaoAK {key}" } places = requests.get(url, headers = headers).json()['documents'] data.extend(places) df=pd.DataFrame(data) df_=df.drop_duplicates().sort_values(by='place_name',ascending=True) df_['si']=df_['address_name'].apply(lambda x: x.split(' ')[0]) df_=df_[(df_['si']=='서울') & (df_['category_group_code']=='FD6')] df_=df_[['place_name','address_name','y','x']] df_['지역구']=df_['address_name'].apply(lambda x: x.split(' ')[1]) return df_ bk=burger(api,'버거킹') bk['burger']='버거킹' mc=burger(api,'맥도날드') mc['burger']='맥도날드' mt=burger(api,'맘스터치') mt['burger']='맘스터치' lt=burger(api,'롯데리아') lt=lt[lt['place_name'].str.contains('롯데리아')] lt['burger']='롯데리아' df=pd.concat([bk,mc,mt,lt],axis=0) df['y']=df['y'].astype(float) df['x']=df['x'].astype(float) df=df.drop_duplicates(['place_name']) df=df.rename(columns={'y':'lat','x':'lng'}) df2=pd.DataFrame(df.groupby(['burger']).count()['place_name']).sort_values(by='place_name',ascending=False) df2=df2.rename(columns={'place_name':'지점 수'}) df2=df2.reset_index() import plotly.express as px fig = px.bar(df2, x='burger', y='지점 수') fig.show() ff=fig.to_json()
Visualization With Pydeck
Uber에서 만든 시각화 라이브러리 Pydeck을 사용해서 버거 브랜드 위치를 지도에 포인트로 해서 아래와 같이 시각화를 해보도록 하겠다. 지도 위에 마우스를 올려 놓으면 해당 지점 이름과 주소를 확인할 수 있다.
bk=bk.rename(columns={'y':'lat','x':'lng'}) bk['lat']=bk['lat'].astype(float) bk['lng']=bk['lng'].astype(float) mc=mc.rename(columns={'y':'lat','x':'lng'}) mc['lat']=mc['lat'].astype(float) mc['lng']=mc['lng'].astype(float) mt=mt.rename(columns={'y':'lat','x':'lng'}) mt['lat']=mt['lat'].astype(float) mt['lng']=mt['lng'].astype(float) lt=lt.rename(columns={'y':'lat','x':'lng'}) lt['lat']=lt['lat'].astype(float) lt['lng']=lt['lng'].astype(float) import pydeck as pdk layer = pdk.Layer( 'ScatterplotLayer', bk, get_position=['lng','lat'], get_radius=200, get_fill_color='[180]', pickable=True, auto_highlight=True, opacity=0.6, ) layer2 = pdk.Layer( 'ScatterplotLayer', mc, get_position=['lng','lat'], get_radius=200, get_fill_color='[90]', pickable=True, auto_highlight=True, opacity=0.6, ) layer3 = pdk.Layer( 'ScatterplotLayer', mt, get_position=['lng','lat'], get_radius=200, get_fill_color='[0,180]', pickable=True, auto_highlight=True, opacity=0.6, ) layer4 = pdk.Layer( 'ScatterplotLayer', lt, get_position=['lng','lat'], get_radius=200, get_fill_color='[320]', pickable=True, auto_highlight=True, opacity=0.6, ) center = [126.986, 37.565] view_state = pdk.ViewState( longitude=center[0], latitude=center[1], zoom=11) r = pdk.Deck(layers=[layer,layer2,layer3,layer4], initial_view_state=view_state, tooltip={"text": "{place_name}\n{address_name}"}) r.show() r.to_html('서울 버거 맵.html')
다음으로 서울시 내 지역별 버거지점 수 기준으로 히트맵을 그리도록 하겠다. 강남3구와 종로구 쪽에 버거가 많이 밀집되어 있는 점을 확인할 수 있다.
heat = pdk.Layer( 'HeatmapLayer', df, get_position='[lng, lat]', auto_highlight=True, opacity=0.5 ) center = [126.986, 37.565] view_state = pdk.ViewState( longitude=center[0], latitude=center[1], zoom=10) r = pdk.Deck(layers=[heat], initial_view_state=view_state) r.show() r.to_html('버거 히트맵.html')
마지막으로 서울 행정구역 별로 총 햄버거 프랜차이즈 총 지점 수와 브랜드멸 지점 수를 아래 지도를 통해서 알아보도록 하겠다.
import json df_gb=pd.DataFrame(df.groupby(['지역구','burger']).count()['place_name']).reset_index() state=json.load(open('C:/Users/banad/Downloads/TL_SCCO_SIG (1).zip.geojson', encoding='utf-8')) code=pd.read_html('https://inasie.github.io/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/5/',encoding='utf-8')[0] code2=code[code['법정동주소'].str.contains('서울특별시')][1:] code2['code']=code2['법정동주소'].apply(lambda x:x.split(' ')[1]) td=pd.merge(left=df_gb,right=code2,how='left',left_on=df_gb['지역구'],right_on=code2['code']) ft=pd.pivot_table(td,index=['지역구','법정동코드'],columns=['burger']).reset_index() ft.columns=['지역구','코드','롯데리아','맘스터치','맥도날드','버거킹'] ft['total']=ft['롯데리아']+ft['맘스터치']+ft['맥도날드']+ft['버거킹'] ft['코드']= ft['코드'].astype(str) for idx, sigun in enumerate(state['features']): code=sigun['properties']['SIG_CD'] if code in ft['코드'].values: total= ft.loc[(ft['코드']==code),'total'].iloc[0] bk_nm= ft.loc[(ft['코드']==code),'버거킹'].iloc[0] mc_nm= ft.loc[(ft['코드']==code),'맥도날드'].iloc[0] mt_nm= ft.loc[(ft['코드']==code),'맘스터치'].iloc[0] lt_nm= ft.loc[(ft['코드']==code),'롯데리아'].iloc[0] addr=ft.loc[(ft['코드']==code),'지역구'].iloc[0] state['features'][idx]['properties']['총 프랜차이즈 버거 지점 수']=float(total)*1000 state['features'][idx]['properties']['버거킹']=float(bk_nm)*1000 state['features'][idx]['properties']['맥도날드']=float(mc_nm)*1000 state['features'][idx]['properties']['맘스터치']=float(mt_nm)*1000 state['features'][idx]['properties']['롯데리아']=float(lt_nm)*1000 state['features'][idx]['properties']['지역구']=addr data=[x for x in state['features'] if len(x['properties'])>1 ] state['features']=data coordinates=[] total=[] region=[] bk2=[] mc2=[] mt2=[] lt2=[] for i in state['features']: coordinates.append(i['geometry']['coordinates'][0]) total.append(i['properties']['총 프랜차이즈 버거 지점 수']) region.append(i['properties']['지역구']) bk2.append(i['properties']['버거킹']) mc2.append(i['properties']['맥도날드']) mt2.append(i['properties']['맘스터치']) lt2.append(i['properties']['롯데리아']) final=pd.DataFrame({'지역':region,'total1':total,'버거킹1':bk2,'맥도날드1':mc2, '맘스터치1':mt2,'롯데리아1':lt2,'coordinates':coordinates }) final['정규화'] = final['total1'] / final['total1'].max() final['total']=final['total1']/1000 final['bk']=final['버거킹1']/1000 final['mc']=final['맥도날드1']/1000 final['mt']=final['맘스터치1']/1000 final['lt']=final['롯데리아1']/1000 final2=pd.merge(left=final,right=kor_eng,how='inner',left_on=final['지역'],right_on=kor_eng['kor']) mm = pdk.Layer( 'PolygonLayer', # 사용할 Layer 타입 final2, # 시각화에 쓰일 데이터프레임 get_polygon='coordinates', # geometry 정보를 담고있는 컬럼 이름 get_fill_color='[0, 255*정규화, 0]', # 각 데이터 별 rgb 또는 rgba 값 (0~255) pickable=True, # 지도와 interactive 한 동작 on auto_highlight=True, # 마우스 오버(hover) 시 박스 출력 extruded = True, get_elevation = 'total1', elevation_scale = 0.2 ) # Set the viewport location center = [126.986, 37.565] view_state = pdk.ViewState( longitude=center[0], latitude=center[1], zoom=10, bearing=15, pitch=45 ) r = pdk.Deck(layers=[mm], initial_view_state=view_state, tooltip={ "html": '''<b>Region:</b> {kor} <br/> <b>Total:</b> {total}<br/> <b>BurgerKing:</b> {bk}<br/> <b>MacDonald:</b> {mc} <br/> <b>MomsTouch:</b> {mt}<br/> <b>Lotteria:</b> {lt}<br/>''' } ) r.show() r.to_html('D:/Download/index.html')
'Data Analysis > LifeStyles' 카테고리의 다른 글
제주도 렌터카 업체 정보 분석 & 시각화 With Python & Mapbox (0) 2021.06.07 서울 크로스핏 박스 지도 시각화 with Python, Mapbox, 카카오 API (0) 2021.05.31 NBA Data Analysis - Top 10 포인트 가드의 어시스트/턴오버 분석 (0) 2021.05.19 국내 SPA 패션 브랜드 매장 수 비교 분석(ZARA, 8Seconds, SPAO, Etc) (1) 2021.04.06 국내 메이저 영화관 브랜드(CJCGV, 메가박스, 롯데시네마) 데이터 분석 (0) 2021.04.05