'중심상가'라 칭하는곳에 가보면 스타벅스가 근처에 여러 매장들이 존재한다.
동네에는 잘 입점하지 않고 사람들의 유동이 많은곳에 스타벅스가 주로 있는거 같다는 의문이 들었다.
여러 요인들이 있겠지만 포괄적인 요인을 대강 알아보기위해 서울시에서 스타벅스의 매장 입점 관계를 알아보기 위해 분석을 했다.
'직장인을 위한 파이썬 데이터분석' 을 이용하였으며 거기서 나오는 기법들을 사용했다.
다음에는 경기 남부를 기준으로 한번 더 해볼예정이다.
from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import matplotlib as mpl
%matplotlib inline
mpl.rcParams['axes.unicode_minus'] = False
path = 'C:/Users/leez/NanumBarunGothic.ttf'
font_name = fm.FontProperties(fname=path, size=50).get_name()
print(font_name)
plt.rc('font', family=font_name)
plt.rcParams["font.size"] = 15
plt.rcParams["figure.figsize"] = (8,5)
NanumBarunGothic
browser = webdriver.Chrome("c:/playwithdata/chromedriver.exe")
url = 'https://www.starbucks.co.kr/store/store_map.do?disp=locale'
browser.get(url)
html 위치 가져오기
seoul_btn ='#container > div > form > fieldset > div > section > article.find_store_cont > article > article:nth-child(4) > div.loca_step1 > div.loca_step1_cont > ul > li:nth-child(1) > a'
browser.find_element_by_css_selector(seoul_btn).click() # 서울 매장 클릭
all_btn = '#mCSB_2_container > ul > li:nth-child(1) > a'
browser.find_element_by_css_selector(all_btn).click()
html = browser.page_source # 크롬 브라우저에 현재 화면에 나타난 웹페이지의 html을 가져옴
soup = BeautifulSoup(html,'html.parser') # 'html.parser' 는 html 문법을 이해하고 웹페이지 정보를 분류
starbucks_soup_list = soup.select('li.quickResultLstCon')
print(len(starbucks_soup_list))
556
starbucks_soup_list[0]
<li class="quickResultLstCon" data-code="3762" data-hlytag="null" data-index="0" data-lat="37.501087" data-long="127.043069" data-name="역삼아레나빌딩" data-storecd="1509" style="background:#fff"> <strong data-my_siren_order_store_yn="N" data-name="역삼아레나빌딩" data-store="1509" data-yn="N">역삼아레나빌딩 </strong> <p class="result_details">서울특별시 강남구 언주로 425 (역삼동)<br/>1522-3232</p> <i class="pin_general">리저브 매장 2번</i></li>
starbucks_store = starbucks_soup_list[0]
name = starbucks_store.select('strong')[0].text.strip()
lat= starbucks_store['data-lat'].strip()
lng= starbucks_store['data-long'].strip()
store_type = starbucks_store.select('i')[0]['class'][0][4:]
address = str(starbucks_store.select('p.result_details')[0]).split('<br/')[0].split('>')[1]
tel=str(starbucks_store.select('p.result_details')[0]).split('<br/>')[1].split('<')[0]
print(name)
print(lat)
print(lng)
print(store_type)
print(address)
print(tel)
역삼아레나빌딩
37.501087
127.043069
general
서울특별시 강남구 언주로 425 (역삼동)
1522-3232
some = str(starbucks_store.select('p.result_details')[0])
print(some)
some = str(starbucks_store.select('p.result_details')[0]).split('<br/')[0]
print(some)
some =str(starbucks_store.select('p.result_details')[0]).split('<br/')[0].split('>')[1]
print(some)
<p class="result_details">서울특별시 강남구 언주로 425 (역삼동)<br/>1522-3232</p>
<p class="result_details">서울특별시 강남구 언주로 425 (역삼동)
서울특별시 강남구 언주로 425 (역삼동)
p class를 str을 이용해 문자열로 바꿔줌
split('<br/') 를 이용해 리스트의 항목으로 나눠줌
split('>')를 한번더해 리스트 항목을 더 만들고 그중에 [1]을 가져온것이 주소
starbucks_list =[]
for item in starbucks_soup_list:
name = item.select('strong')[0].text.strip()
lat= item['data-lat'].strip()
lng= item['data-long'].strip()
store_type = item.select('i')[0]['class'][0][4:]
address = str(item.select('p.result_details')[0]).split('<br/')[0].split('>')[1]
tel=str(item.select('p.result_details')[0]).split('<br/>')[1].split('<')[0]
starbucks_list.append([name,lat,lng,store_type,address,tel])
columns =['매장명','위도','경도','매장타입','주소','전화번호']
seoul_starbucks_df = pd.DataFrame(starbucks_list,columns=columns)
seoul_starbucks_df.head()
매장명 | 위도 | 경도 | 매장타입 | 주소 | 전화번호 | |
---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 37.501087 | 127.043069 | general | 서울특별시 강남구 언주로 425 (역삼동) | 1522-3232 |
1 | 논현역사거리 | 37.510178 | 127.022223 | general | 서울특별시 강남구 강남대로 538 (논현동) | 1522-3232 |
2 | 신사역성일빌딩 | 37.514132 | 127.020563 | general | 서울특별시 강남구 강남대로 584 (논현동) | 1522-3232 |
3 | 국기원사거리 | 37.499517 | 127.031495 | general | 서울특별시 강남구 테헤란로 125 (역삼동) | 1522-3232 |
4 | 스탈릿대치R | 37.494668 | 127.062583 | reserve | 서울특별시 강남구 남부순환로 2947 (대치동) | 1522-3232 |
seoul_starbucks_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 556 entries, 0 to 555
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 매장명 556 non-null object
1 위도 556 non-null object
2 경도 556 non-null object
3 매장타입 556 non-null object
4 주소 556 non-null object
5 전화번호 556 non-null object
dtypes: object(6)
memory usage: 26.2+ KB
seoul_starbucks_df.to_csv('C:\playwithdata\starbuck_in_seoul.csv',encoding='cp949')
위 세개 데이터를 추가했다.
total_seoul_loc = pd.read_csv(r'C:\playwithdata\스타벅스\서울시행정구역정보.csv',encoding='cp949')
total_seoul_loc = total_seoul_loc.drop(['순번','시군구명_영문','ESRI_PK'],axis=1)
total_seoul_loc
시군구코드 | 시군구명 | 위도 | 경도 | |
---|---|---|---|---|
0 | 11320 | 도봉구 | 37.665861 | 127.031767 |
1 | 11380 | 은평구 | 37.617612 | 126.922700 |
2 | 11230 | 동대문구 | 37.583801 | 127.050700 |
3 | 11590 | 동작구 | 37.496504 | 126.944307 |
4 | 11545 | 금천구 | 37.460097 | 126.900155 |
5 | 11530 | 구로구 | 37.495486 | 126.858121 |
6 | 11110 | 종로구 | 37.599100 | 126.986149 |
7 | 11305 | 강북구 | 37.646995 | 127.014716 |
8 | 11260 | 중랑구 | 37.595379 | 127.093967 |
9 | 11680 | 강남구 | 37.495985 | 127.066409 |
10 | 11500 | 강서구 | 37.565762 | 126.822656 |
11 | 11140 | 중구 | 37.557945 | 126.994190 |
12 | 11740 | 강동구 | 37.549208 | 127.146482 |
13 | 11215 | 광진구 | 37.548144 | 127.085753 |
14 | 11440 | 마포구 | 37.562291 | 126.908780 |
15 | 11650 | 서초구 | 37.476953 | 127.037810 |
16 | 11290 | 성북구 | 37.606991 | 127.023218 |
17 | 11350 | 노원구 | 37.655264 | 127.077120 |
18 | 11710 | 송파구 | 37.504853 | 127.114482 |
19 | 11410 | 서대문구 | 37.582037 | 126.935667 |
20 | 11470 | 양천구 | 37.527062 | 126.856153 |
21 | 11560 | 영등포구 | 37.520641 | 126.913924 |
22 | 11620 | 관악구 | 37.465399 | 126.943807 |
23 | 11200 | 성동구 | 37.550675 | 127.040962 |
24 | 11170 | 용산구 | 37.531101 | 126.981074 |
sgg_pop_df = pd.read_csv(r'C:\playwithdata\스타벅스\주민등록인원수.txt',sep='\t',header=2)
sgg_pop_df
기간 | 자치구 | 세대 | 계 | 남자 | 여자 | 계.1 | 남자.1 | 여자.1 | 계.2 | 남자.2 | 여자.2 | 세대당인구 | 65세이상고령자 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2021.1/4 | 합계 | 4,400,403 | 9,828,094 | 4,774,856 | 5,053,238 | 9,598,484 | 4,667,524 | 4,930,960 | 229,610 | 107,332 | 122,278 | 2.18 | 1,567,819 |
1 | 2021.1/4 | 종로구 | 74,113 | 156,567 | 75,772 | 80,795 | 147,296 | 71,644 | 75,652 | 9,271 | 4,128 | 5,143 | 1.99 | 27,781 |
2 | 2021.1/4 | 중구 | 63,746 | 133,708 | 65,312 | 68,396 | 124,552 | 60,851 | 63,701 | 9,156 | 4,461 | 4,695 | 1.95 | 24,767 |
3 | 2021.1/4 | 용산구 | 112,881 | 243,336 | 118,120 | 125,216 | 229,013 | 110,181 | 118,832 | 14,323 | 7,939 | 6,384 | 2.03 | 39,575 |
4 | 2021.1/4 | 성동구 | 135,883 | 298,421 | 145,358 | 153,063 | 291,906 | 142,506 | 149,400 | 6,515 | 2,852 | 3,663 | 2.15 | 45,968 |
5 | 2021.1/4 | 광진구 | 166,638 | 356,191 | 171,131 | 185,060 | 343,392 | 165,747 | 177,645 | 12,799 | 5,384 | 7,415 | 2.06 | 50,370 |
6 | 2021.1/4 | 동대문구 | 165,924 | 352,570 | 173,309 | 179,261 | 338,875 | 167,895 | 170,980 | 13,695 | 5,414 | 8,281 | 2.04 | 60,868 |
7 | 2021.1/4 | 중랑구 | 185,506 | 396,807 | 195,639 | 201,168 | 392,041 | 193,752 | 198,289 | 4,766 | 1,887 | 2,879 | 2.11 | 69,841 |
8 | 2021.1/4 | 성북구 | 193,965 | 444,295 | 213,586 | 230,709 | 434,826 | 209,902 | 224,924 | 9,469 | 3,684 | 5,785 | 2.24 | 73,158 |
9 | 2021.1/4 | 강북구 | 144,410 | 307,537 | 149,582 | 157,955 | 304,078 | 148,306 | 155,772 | 3,459 | 1,276 | 2,183 | 2.11 | 62,893 |
10 | 2021.1/4 | 도봉구 | 138,120 | 323,752 | 157,562 | 166,190 | 321,717 | 156,810 | 164,907 | 2,035 | 752 | 1,283 | 2.33 | 62,360 |
11 | 2021.1/4 | 노원구 | 217,272 | 522,225 | 251,719 | 270,506 | 518,278 | 249,942 | 268,336 | 3,947 | 1,777 | 2,170 | 2.39 | 85,906 |
12 | 2021.1/4 | 은평구 | 212,725 | 479,607 | 229,589 | 250,018 | 475,501 | 227,910 | 247,591 | 4,106 | 1,679 | 2,427 | 2.24 | 85,140 |
13 | 2021.1/4 | 서대문구 | 143,180 | 318,814 | 151,331 | 167,483 | 308,482 | 147,655 | 160,827 | 10,332 | 3,676 | 6,656 | 2.15 | 53,440 |
14 | 2021.1/4 | 마포구 | 177,170 | 378,216 | 177,377 | 200,839 | 368,518 | 173,624 | 194,894 | 9,698 | 3,753 | 5,945 | 2.08 | 53,494 |
15 | 2021.1/4 | 양천구 | 180,682 | 456,019 | 223,450 | 232,569 | 452,677 | 222,010 | 230,667 | 3,342 | 1,440 | 1,902 | 2.51 | 66,231 |
16 | 2021.1/4 | 강서구 | 267,442 | 582,804 | 280,942 | 301,862 | 577,320 | 278,444 | 298,876 | 5,484 | 2,498 | 2,986 | 2.16 | 89,377 |
17 | 2021.1/4 | 구로구 | 180,027 | 426,675 | 212,092 | 214,583 | 401,074 | 198,034 | 203,040 | 25,601 | 14,058 | 11,543 | 2.23 | 70,717 |
18 | 2021.1/4 | 금천구 | 114,402 | 244,564 | 124,300 | 120,264 | 229,844 | 116,322 | 113,522 | 14,720 | 7,978 | 6,742 | 2.01 | 39,781 |
19 | 2021.1/4 | 영등포구 | 184,133 | 403,070 | 200,380 | 202,690 | 377,590 | 186,692 | 190,898 | 25,480 | 13,688 | 11,792 | 2.05 | 61,197 |
20 | 2021.1/4 | 동작구 | 183,579 | 398,205 | 192,187 | 206,018 | 388,730 | 188,045 | 200,685 | 9,475 | 4,142 | 5,333 | 2.12 | 65,396 |
21 | 2021.1/4 | 관악구 | 273,736 | 504,140 | 252,400 | 251,740 | 490,352 | 246,097 | 244,255 | 13,788 | 6,303 | 7,485 | 1.79 | 78,400 |
22 | 2021.1/4 | 서초구 | 172,181 | 425,103 | 203,489 | 221,614 | 421,315 | 201,619 | 219,696 | 3,788 | 1,870 | 1,918 | 2.45 | 60,209 |
23 | 2021.1/4 | 강남구 | 233,363 | 539,538 | 258,205 | 281,333 | 534,796 | 255,880 | 278,916 | 4,742 | 2,325 | 2,417 | 2.29 | 75,602 |
24 | 2021.1/4 | 송파구 | 280,237 | 667,115 | 321,658 | 345,457 | 661,411 | 319,047 | 342,364 | 5,704 | 2,611 | 3,093 | 2.36 | 94,145 |
25 | 2021.1/4 | 강동구 | 199,088 | 468,815 | 230,366 | 238,449 | 464,900 | 228,609 | 236,291 | 3,915 | 1,757 | 2,158 | 2.34 | 71,203 |
ssg_pop_df_final =sgg_pop_df[['자치구','계']][1:]
ssg_pop_df_final.head()
자치구 | 계 | |
---|---|---|
1 | 종로구 | 156,567 |
2 | 중구 | 133,708 |
3 | 용산구 | 243,336 |
4 | 성동구 | 298,421 |
5 | 광진구 | 356,191 |
ssg_pop_df_final.columns = ['시군구명','주민등록인구']
ssg_pop_df_final.head()
시군구명 | 주민등록인구 | |
---|---|---|
1 | 종로구 | 156,567 |
2 | 중구 | 133,708 |
3 | 용산구 | 243,336 |
4 | 성동구 | 298,421 |
5 | 광진구 | 356,191 |
ssg_biz_df = pd.read_csv(r'C:\playwithdata\스타벅스\사업체현황.txt',sep='\t',header=1)
ssg_biz_df= ssg_biz_df[['자치구','동','종사자수','사업체수',]]
ssg_biz_df['동'].astype(str)
0 동
1 합계
2 소계
3 사직동
4 삼청동
...
446 둔촌1동
447 둔촌2동
448 암사1동
449 천호2동
450 길동
Name: 동, Length: 451, dtype: object
ssg_biz_df= ssg_biz_df[ssg_biz_df['동']=='소계'].reset_index()
ssg_biz_df.drop(['동','index'],axis=1,inplace=True)
ssg_biz_df.columns = ['시군구명','종사자수','사업체수']
seoul_starbucks=pd.read_csv('C:\playwithdata\starbuck_in_seoul.csv',encoding='cp949',index_col=0)
seoul_starbucks.head()
매장명 | 위도 | 경도 | 매장타입 | 주소 | 전화번호 | |
---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 37.501087 | 127.043069 | general | 서울특별시 강남구 언주로 425 (역삼동) | 1522-3232 |
1 | 논현역사거리 | 37.510178 | 127.022223 | general | 서울특별시 강남구 강남대로 538 (논현동) | 1522-3232 |
2 | 신사역성일빌딩 | 37.514132 | 127.020563 | general | 서울특별시 강남구 강남대로 584 (논현동) | 1522-3232 |
3 | 국기원사거리 | 37.499517 | 127.031495 | general | 서울특별시 강남구 테헤란로 125 (역삼동) | 1522-3232 |
4 | 스탈릿대치R | 37.494668 | 127.062583 | reserve | 서울특별시 강남구 남부순환로 2947 (대치동) | 1522-3232 |
ssg_name = []
for i in seoul_starbucks['주소']:
ssg = i.split()[1]
ssg_name.append(ssg)
seoul_starbucks['시군구명']=ssg_name
seoul_starbucks
매장명 | 위도 | 경도 | 매장타입 | 주소 | 전화번호 | 시군구명 | |
---|---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 37.501087 | 127.043069 | general | 서울특별시 강남구 언주로 425 (역삼동) | 1522-3232 | 강남구 |
1 | 논현역사거리 | 37.510178 | 127.022223 | general | 서울특별시 강남구 강남대로 538 (논현동) | 1522-3232 | 강남구 |
2 | 신사역성일빌딩 | 37.514132 | 127.020563 | general | 서울특별시 강남구 강남대로 584 (논현동) | 1522-3232 | 강남구 |
3 | 국기원사거리 | 37.499517 | 127.031495 | general | 서울특별시 강남구 테헤란로 125 (역삼동) | 1522-3232 | 강남구 |
4 | 스탈릿대치R | 37.494668 | 127.062583 | reserve | 서울특별시 강남구 남부순환로 2947 (대치동) | 1522-3232 | 강남구 |
... | ... | ... | ... | ... | ... | ... | ... |
551 | 사가정역 | 37.579594 | 127.087966 | general | 서울특별시 중랑구 면목로 310 | 1522-3232 | 중랑구 |
552 | 상봉역 | 37.596890 | 127.086470 | general | 서울특별시 중랑구 망우로 307 (상봉동) | 1522-3232 | 중랑구 |
553 | 묵동이마트 | 37.613433 | 127.077484 | general | 서울특별시 중랑구 동일로 932 (묵동, 묵동자이아파트) (묵동이마트 B1층) | 1522-3232 | 중랑구 |
554 | 묵동 | 37.615368 | 127.076633 | general | 서울특별시 중랑구 동일로 952 | 1522-3232 | 중랑구 |
555 | 중화역 | 37.601709 | 127.078411 | general | 서울특별시 중랑구 봉화산로 35 1,2층 | 1522-3232 | 중랑구 |
556 rows × 7 columns
위 파일 변수명
위도 경도 : total_seoul_loc
주민등록인구 : ssg_pop_df_final
사업체수 :ssg_biz_df
seoul_starbucks_count = seoul_starbucks.pivot_table(index='시군구명',values='매장명',aggfunc='count').rename(columns={'매장명':'스타벅스_매장수'})
seoul_starbucks_count
스타벅스_매장수 | |
---|---|
시군구명 | |
강남구 | 85 |
강동구 | 15 |
강북구 | 5 |
강서구 | 19 |
관악구 | 11 |
광진구 | 17 |
구로구 | 11 |
금천구 | 11 |
노원구 | 13 |
도봉구 | 3 |
동대문구 | 9 |
동작구 | 11 |
마포구 | 32 |
서대문구 | 20 |
서초구 | 48 |
성동구 | 11 |
성북구 | 14 |
송파구 | 33 |
양천구 | 17 |
영등포구 | 38 |
용산구 | 21 |
은평구 | 8 |
종로구 | 40 |
중구 | 56 |
중랑구 | 8 |
seoul_sgg = pd.merge(total_seoul_loc,seoul_starbucks_count,how='left',on='시군구명')
seoul_sgg =pd.merge(seoul_sgg,ssg_pop_df_final,how='left',on='시군구명')
seoul_sgg =pd.merge(seoul_sgg,ssg_biz_df,how='left',on='시군구명')
seoul_sgg
시군구코드 | 시군구명 | 위도 | 경도 | 스타벅스_매장수 | 주민등록인구 | 종사자수 | 사업체수 | |
---|---|---|---|---|---|---|---|---|
0 | 11320 | 도봉구 | 37.665861 | 127.031767 | 3 | 323,752 | 72,939 | 18,628 |
1 | 11380 | 은평구 | 37.617612 | 126.922700 | 8 | 479,607 | 93,631 | 24,681 |
2 | 11230 | 동대문구 | 37.583801 | 127.050700 | 9 | 352,570 | 138,400 | 31,324 |
3 | 11590 | 동작구 | 37.496504 | 126.944307 | 11 | 398,205 | 106,159 | 19,793 |
4 | 11545 | 금천구 | 37.460097 | 126.900155 | 11 | 244,564 | 242,686 | 33,814 |
5 | 11530 | 구로구 | 37.495486 | 126.858121 | 11 | 426,675 | 225,668 | 38,756 |
6 | 11110 | 종로구 | 37.599100 | 126.986149 | 40 | 156,567 | 260,446 | 39,679 |
7 | 11305 | 강북구 | 37.646995 | 127.014716 | 5 | 307,537 | 73,904 | 19,014 |
8 | 11260 | 중랑구 | 37.595379 | 127.093967 | 8 | 396,807 | 103,345 | 28,228 |
9 | 11680 | 강남구 | 37.495985 | 127.066409 | 85 | 539,538 | 698,840 | 71,027 |
10 | 11500 | 강서구 | 37.565762 | 126.822656 | 19 | 582,804 | 257,494 | 39,458 |
11 | 11140 | 중구 | 37.557945 | 126.994190 | 56 | 133,708 | 392,568 | 60,127 |
12 | 11740 | 강동구 | 37.549208 | 127.146482 | 15 | 468,815 | 141,770 | 29,080 |
13 | 11215 | 광진구 | 37.548144 | 127.085753 | 17 | 356,191 | 126,305 | 24,445 |
14 | 11440 | 마포구 | 37.562291 | 126.908780 | 32 | 378,216 | 247,276 | 37,290 |
15 | 11650 | 서초구 | 37.476953 | 127.037810 | 48 | 425,103 | 438,985 | 46,940 |
16 | 11290 | 성북구 | 37.606991 | 127.023218 | 14 | 444,295 | 111,005 | 23,617 |
17 | 11350 | 노원구 | 37.655264 | 127.077120 | 13 | 522,225 | 116,684 | 26,618 |
18 | 11710 | 송파구 | 37.504853 | 127.114482 | 33 | 667,115 | 341,201 | 48,644 |
19 | 11410 | 서대문구 | 37.582037 | 126.935667 | 20 | 318,814 | 113,819 | 20,095 |
20 | 11470 | 양천구 | 37.527062 | 126.856153 | 17 | 456,019 | 121,582 | 25,894 |
21 | 11560 | 영등포구 | 37.520641 | 126.913924 | 38 | 403,070 | 373,478 | 42,370 |
22 | 11620 | 관악구 | 37.465399 | 126.943807 | 11 | 504,140 | 115,329 | 25,505 |
23 | 11200 | 성동구 | 37.550675 | 127.040962 | 11 | 298,421 | 178,243 | 28,343 |
24 | 11170 | 용산구 | 37.531101 | 126.981074 | 21 | 243,336 | 135,240 | 20,254 |
seoul_sgg.to_csv('C:\playwithdata\seoul_sgg.csv',encoding='cp949')
folium을 이용하여 각 지점들을 지도위에 표현했다.
import folium # 데이터를 지도위에 표현함
seoul_starbucks = pd.read_csv('C:\playwithdata\starbuck_in_seoul.csv',encoding='cp949',index_col=0)
seoul_starbucks.head()
매장명 | 위도 | 경도 | 매장타입 | 주소 | 전화번호 | |
---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 37.501087 | 127.043069 | general | 서울특별시 강남구 언주로 425 (역삼동) | 1522-3232 |
1 | 논현역사거리 | 37.510178 | 127.022223 | general | 서울특별시 강남구 강남대로 538 (논현동) | 1522-3232 |
2 | 신사역성일빌딩 | 37.514132 | 127.020563 | general | 서울특별시 강남구 강남대로 584 (논현동) | 1522-3232 |
3 | 국기원사거리 | 37.499517 | 127.031495 | general | 서울특별시 강남구 테헤란로 125 (역삼동) | 1522-3232 |
4 | 스탈릿대치R | 37.494668 | 127.062583 | reserve | 서울특별시 강남구 남부순환로 2947 (대치동) | 1522-3232 |
starbucks_map = folium.Map(
location = [37.573050,126.979189],
tiles = 'Stamen Terrain',
zoom_start=11
)
starbucks_map
for idx in seoul_starbucks.index:
lat =seoul_starbucks.loc[idx,'위도']
lng =seoul_starbucks.loc[idx,'경도']
folium.CircleMarker(
location=[lat,lng],
fill =True,
fill_color = 'green',
fill_opacity =1,
color = 'yellow',
weight=1,
radius=3,
).add_to(starbucks_map)
starbucks_map
강남구와 종로구에 스타벅스매장의 수가 많은것을 확인할수 있다.
starbucks_map2 = folium.Map(
location = [37.573050,126.979189],
tiles = 'Stamen Terrain',
zoom_start=11
)
for idx in seoul_starbucks.index:
lat =seoul_starbucks.loc[idx,'위도']
lng =seoul_starbucks.loc[idx,'경도']
store_type = seoul_starbucks.loc[idx,'매장타입']
fillColor=''
if store_type == 'general':
fillColor = 'black'
size =1
elif store_type == 'reserve':
fillColor = 'blue'
size =5
elif store_type == 'generalDT':
fillColor = 'red'
size =5
folium.CircleMarker(
location=[lat,lng],
color = fillColor,
fill =True,
fill_color = fillColor,
fill_opacity =1,
weight=1,
radius=size
).add_to(starbucks_map2)
starbucks_map2
서울시 스타벅스 매장의 특징
드라이브스루 :빨강
리저브 : 파랑
일반매장 : 검정
서울 외곽에 드라이브 스루 매장이 많이 분포되어있고 ,강남과 종로에는 리저브 매장이 많이 분포되있는걸 확인할수있다.
import json
seoul_sgg_stat = pd.read_csv('C:\playwithdata\seoul_sgg.csv',encoding='cp949',index_col=0)
seoul_sgg_stat.head()
시군구코드 | 시군구명 | 위도 | 경도 | 스타벅스_매장수 | 주민등록인구 | 종사자수 | 사업체수 | |
---|---|---|---|---|---|---|---|---|
0 | 11320 | 도봉구 | 37.665861 | 127.031767 | 3 | 323,752 | 72,939 | 18,628 |
1 | 11380 | 은평구 | 37.617612 | 126.922700 | 8 | 479,607 | 93,631 | 24,681 |
2 | 11230 | 동대문구 | 37.583801 | 127.050700 | 9 | 352,570 | 138,400 | 31,324 |
3 | 11590 | 동작구 | 37.496504 | 126.944307 | 11 | 398,205 | 106,159 | 19,793 |
4 | 11545 | 금천구 | 37.460097 | 126.900155 | 11 | 244,564 | 242,686 | 33,814 |
ssg_geojson_file_path ='C:\playwithdata\스타벅스\seoul_sgg.geojson'
seoul_sgg_geo = json.load(open(ssg_geojson_file_path,encoding='utf=8'))
seoul_sgg_geo['features'][0]['properties']
{'SIG_CD': '11320',
'SIG_KOR_NM': '도봉구',
'SIG_ENG_NM': 'Dobong-gu',
'ESRI_PK': 0,
'SHAPE_AREA': 0.00210990544544,
'SHAPE_LEN': 0.239901251347}
starbucks_bubble = folium.Map(
location=[37.573050,126.979189],
tiles = 'CartoDB dark_matter', #배경지도 할당
zoom_start=11
)
def style_function(feature):
return {
'opacity' :0.7,
'weight' : 1,
'color':'white',
'fillOpacity':0,
'dashArray':'5,5',
}
folium.GeoJson(
seoul_sgg_geo,
style_function = style_function
).add_to(starbucks_bubble)
starbucks_bubble
starbucks_mean = seoul_sgg_stat['스타벅스_매장수'].mean()
print(starbucks_mean)
22.24
for idx in seoul_sgg_stat.index:
lat = seoul_sgg_stat.loc[idx, '위도']
lng = seoul_sgg_stat.loc[idx, '경도']
count = seoul_sgg_stat.loc[idx, '스타벅스_매장수']
if count > starbucks_mean:
fillColor = 'red'
else:
fillColor = 'blue'
folium.CircleMarker(
location=[lat, lng],
color='grey',
fill_color=fillColor,
fill_opacity=0.7,
weight=1.5,
radius=count/2
).add_to(starbucks_bubble)
starbucks_bubble
시군구별 평균보다 매장수가 많은곳은 빨간색으로 적은곳은 파란색으로 나타냈다.
ssg_geojson_file_path ='C:\playwithdata\스타벅스\seoul_sgg.geojson'
seoul_sgg_geo_2 = json.load(open(ssg_geojson_file_path,encoding='utf=8'))
starbucks_choropleth = folium.Map(
location=[37.573050,126.979189],
tiles = 'CartoDB dark_matter', #배경지도 할당
zoom_start=11
)
folium.Choropleth(
geo_data=seoul_sgg_geo_2,
data=seoul_sgg_stat,
columns=['시군구명', '스타벅스_매장수'],
fill_color = 'YlGn',
fill_opacity=0.7,
line_opacity=0.5,
key_on='properties.SIG_KOR_NM'
).add_to(starbucks_choropleth)
starbucks_choropleth
geo_data : 지도 데이터를 지정
data : 데이터프레임 데이터를 지정
** columns : 두개의 값을 리스트로 넣어준다 . 첫번째값은 지도와 매칭되는 값(SIG_KOR_NM == 시군구명) , 두번째값은 value로 단계구분을 지정할 정수값
key_on : 'properties.SIG_KOR_NM'를 입력해 '시군구명' 칼럼과 매칭
가정 : 거주인원이 많은 지역에 스타벅스 매장이 많이 입지해 있을것이다.
seoul_sgg_stat = pd.read_csv('C:\playwithdata\seoul_sgg.csv',encoding='cp949',index_col=0)
seoul_sgg_stat.head()
시군구코드 | 시군구명 | 위도 | 경도 | 스타벅스_매장수 | 주민등록인구 | 종사자수 | 사업체수 | |
---|---|---|---|---|---|---|---|---|
0 | 11320 | 도봉구 | 37.665861 | 127.031767 | 3 | 323,752 | 72,939 | 18,628 |
1 | 11380 | 은평구 | 37.617612 | 126.922700 | 8 | 479,607 | 93,631 | 24,681 |
2 | 11230 | 동대문구 | 37.583801 | 127.050700 | 9 | 352,570 | 138,400 | 31,324 |
3 | 11590 | 동작구 | 37.496504 | 126.944307 | 11 | 398,205 | 106,159 | 19,793 |
4 | 11545 | 금천구 | 37.460097 | 126.900155 | 11 | 244,564 | 242,686 | 33,814 |
def value_chanes(name): # 문자열을 float형으로 바꿔주기위해 설정함
for i in range(len(seoul_sgg_stat[name])):
seoul_sgg_stat[name][i] = seoul_sgg_stat[name][i].replace(',',"")
seoul_sgg_stat[name] = seoul_sgg_stat[name].astype(float)
value_chanes('주민등록인구')
value_chanes('종사자수')
value_chanes('사업체수');
<ipython-input-61-cc989170fbfb>:3: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
seoul_sgg_stat[name][i] = seoul_sgg_stat[name][i].replace(',',"")
seoul_sgg_stat.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 25 entries, 0 to 24
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 시군구코드 25 non-null int64
1 시군구명 25 non-null object
2 위도 25 non-null float64
3 경도 25 non-null float64
4 스타벅스_매장수 25 non-null int64
5 주민등록인구 25 non-null float64
6 종사자수 25 non-null float64
7 사업체수 25 non-null float64
dtypes: float64(5), int64(2), object(1)
memory usage: 2.4+ KB
ssg_geojson_file_path ='C:\playwithdata\스타벅스\seoul_sgg.geojson'
seoul_sgg_geo = json.load(open(ssg_geojson_file_path,encoding='utf=8'))
starbucks_choropleth = folium.Map(
location=[37.573050,126.979189],
tiles = 'CartoDB dark_matter', #배경지도 할당
min_zoom = 10,
max_zoom =12,
zoom_start=11
)
folium.Choropleth(
geo_data=seoul_sgg_geo_2,
data=seoul_sgg_stat,
columns=['시군구명', '주민등록인구'],
fill_color = 'YlGn',
fill_opacity=0.7,
line_opacity=0.5,
key_on='properties.SIG_KOR_NM'
).add_to(starbucks_choropleth)
starbucks_choropleth
seoul_sgg_stat_sort = seoul_sgg_stat.sort_values(['주민등록인구'],ascending=False)
plt.figure(figsize=(22,5))
plt.bar(seoul_sgg_stat_sort['시군구명'],seoul_sgg_stat_sort['주민등록인구'],color='green')
plt.title('서울시 구별 주민등록인구수 ', fontsize=20)
plt.xlabel('시군구명', fontsize=18)
plt.ylabel('주민등록인구', fontsize=18)
plt.show()
주민등록 인구수는 송파구 >> 강서구 >> 강남구 순으로 확인
seoul_sgg_stat['만명당_매장수'] = seoul_sgg_stat['스타벅스_매장수']/(seoul_sgg_stat['주민등록인구']/10000)
SGG_GEOJSON_FILE_PATH = 'C:\playwithdata\스타벅스\seoul_sgg.geojson'
seoul_sgg_geo_1 = json.load(open(SGG_GEOJSON_FILE_PATH, encoding='utf-8'))
viz_map_1 = folium.Map(
location=[37.573050, 126.979189],
tiles='CartoDB dark_matter',
zoom_start=11
)
def style_function(feature):
return {
'opacity': 0.7,
'weight': 1,
'fillOpacity':0,
}
folium.GeoJson(
seoul_sgg_geo_2,
style_function=style_function,
).add_to(viz_map_1)
top = seoul_sgg_stat ['만명당_매장수'].quantile(0.9) # 상위 10%값을 얻기 위한 코드
for idx in seoul_sgg_stat.index:
lat = seoul_sgg_stat.loc[idx, '위도']
lng = seoul_sgg_stat.loc[idx, '경도']
r = seoul_sgg_stat.loc[idx, '만명당_매장수']
if r > top:
fillColor = 'red'
else:
fillColor = 'green'
folium.CircleMarker(
location=[lat, lng],
color='#FFFF00',
fill_color=fillColor,
fill_opacity=0.7,
weight=1.5,
radius= r * 10
).add_to(viz_map_1)
viz_map_1
인구수대비 스타벅스의 수는 종로구 >> 중구 >> 강남구 이렇게 나타므로
주민등록인구와 스타벅스 매장수는 서로 비례하지 않은것으로 나타난다.
가정 : 직장인이 많은 지역에 스타벅스 매장이 많이 입지해 있을것이다.
seoul_sgg_stat['종사자수_만명당_매장수'] = seoul_sgg_stat['스타벅스_매장수']/(seoul_sgg_stat['종사자수']/10000)
seoul_sgg_stat.head()
시군구코드 | 시군구명 | 위도 | 경도 | 스타벅스_매장수 | 주민등록인구 | 종사자수 | 사업체수 | 만명당_매장수 | 종사자수_만명당_매장수 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 11320 | 도봉구 | 37.665861 | 127.031767 | 3 | 323752.0 | 72939.0 | 18628.0 | 0.092664 | 0.411303 |
1 | 11380 | 은평구 | 37.617612 | 126.922700 | 8 | 479607.0 | 93631.0 | 24681.0 | 0.166803 | 0.854418 |
2 | 11230 | 동대문구 | 37.583801 | 127.050700 | 9 | 352570.0 | 138400.0 | 31324.0 | 0.255268 | 0.650289 |
3 | 11590 | 동작구 | 37.496504 | 126.944307 | 11 | 398205.0 | 106159.0 | 19793.0 | 0.276240 | 1.036182 |
4 | 11545 | 금천구 | 37.460097 | 126.900155 | 11 | 244564.0 | 242686.0 | 33814.0 | 0.449780 | 0.453261 |
seoul_sgg_geo_1 = json.load(open(SGG_GEOJSON_FILE_PATH, encoding='utf-8'))
viz_map_1 = folium.Map(
location=[37.573050, 126.979189],
tiles='CartoDB dark_matter',
zoom_start=11
)
folium.GeoJson(
seoul_sgg_geo_1,
style_function=style_function,
).add_to(viz_map_1)
top = seoul_sgg_stat['종사자수_만명당_매장수'].quantile(0.9) # 상위값 3개를 가져오기 위함
for idx in seoul_sgg_stat.index:
name = seoul_sgg_stat.at[idx, '시군구명']
lat = seoul_sgg_stat.loc[idx, '위도']
lng = seoul_sgg_stat.loc[idx, '경도']
r = seoul_sgg_stat.loc[idx, '종사자수_만명당_매장수']
if r > top:
fillColor = '#FF3300'
else:
fillColor = '#CCFF33'
folium.CircleMarker(
location=[lat, lng],
color='#FFFF00',
fill_color=fillColor,
fill_opacity=0.7,
weight=1.5,
radius= r * 10
).add_to(viz_map_1)
viz_map_1
서대문구 >> 용산구 >> 종로구 순으로 보였다.
seoul_sgg_stat_sort2 = seoul_sgg_stat.sort_values(['종사자수'],ascending=False)
seoul_sgg_stat_sort3 =seoul_sgg_stat.sort_values(['스타벅스_매장수'],ascending=False)
plt.figure(figsize=(22,10))
plt.subplot(211)
plt.bar(seoul_sgg_stat_sort2['시군구명'],seoul_sgg_stat_sort2['종사자수'],color='green')
plt.title('서울시 구별 종사자수 ', fontsize=20)
plt.ylabel('종사자수', fontsize=18)
plt.subplot(212)
plt.bar(seoul_sgg_stat_sort3['시군구명'],seoul_sgg_stat_sort3['스타벅스_매장수'],color='green')
plt.title('서울시 구별 스타벅스 매장수 ', fontsize=20)
plt.ylabel('스타벅스_매장수', fontsize=18)
plt.show()
종사자수와 스타벅스 매장수가 어느정도 비례관계를 보이므로 두번째 가설은 어느정도 타당한것으로 보인다.
보완해야할점