지난 포스트에서 스타벅스와 이디야 홈페이지에서 각각의 매장정보를 스크랩하는 방법을 정리했습니다. 이번엔 수집한 정보를 바탕으로 간단한 시각화와 함께 '이디야는 스타벅스 옆에 있을까?'란 주제로 데이터를 살펴보겠습니다. 이 포스트는 '제로베이스 데이터스쿨'에서 과제로 제출한 것을 일부 수정한 것입니다.
수집했던 정보를 먼저 불러오겠습니다.
import pandas as pd
df_starbucks = pd.read_csv('./data/starbucks_info.csv')
df_ediya = pd.read_csv('./data/ediya_info.csv')
분석을 위해 '구분' 컬럼을 만들어 주겠습니다.
df_starbucks['구분'] = '스타벅스'
df_ediya['구분'] = '이디야'
df_ediya
store | 구 | addr | lat | lng | 구분 | |
---|---|---|---|---|---|---|
0 | 강남YMCA점 | 강남구 | 서울 강남구 논현동 230-2 | 37.509943 | 127.035702 | 이디야 |
1 | 강남구청역아이티웨딩점 | 강남구 | 서울 강남구 학동로 338 (논현동, 강남파라곤) | 37.516542 | 127.040160 | 이디야 |
2 | 강남논현학동점 | 강남구 | 서울 강남구 논현로131길 28 (논현동) | 37.514080 | 127.028106 | 이디야 |
3 | 강남대치점 | 강남구 | 서울 강남구 역삼로 415 (대치동, 성진빌딩) | 37.501339 | 127.052429 | 이디야 |
4 | 강남도산점 | 강남구 | 서울 강남구 도산대로37길 20 (신사동) | 37.501339 | 127.052429 | 이디야 |
... | ... | ... | ... | ... | ... | ... |
609 | 중랑교차로점 | 중랑구 | 서울 중랑구 동일로 683 (면목동) | 37.591448 | 127.079882 | 이디야 |
610 | 중랑묵동점 | 중랑구 | 서울 중랑구 동일로 932 (묵동, 묵동자이아파트) | 37.613353 | 127.077536 | 이디야 |
611 | 중랑역점 | 중랑구 | 서울 중랑구 망우로 198 (상봉동) | 37.593285 | 127.074889 | 이디야 |
612 | 중화동점 | 중랑구 | 서울 중랑구 동일로129길 1 (중화동) | 37.599384 | 127.079543 | 이디야 |
613 | 화랑대역점 | 중랑구 | 서울 중랑구 신내로25가길 2 (묵동, 현동학당) | 37.619540 | 127.084137 | 이디야 |
614 rows × 6 columns
df_starbucks
store | 구 | addr | lat | lng | 구분 | |
---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 강남구 | 서울특별시 강남구 언주로 425 (역삼동) | 37.501087 | 127.043069 | 스타벅스 |
1 | 논현역사거리 | 강남구 | 서울특별시 강남구 강남대로 538 (논현동) | 37.510178 | 127.022223 | 스타벅스 |
2 | 신사역성일빌딩 | 강남구 | 서울특별시 강남구 강남대로 584 (논현동) | 37.513931 | 127.020606 | 스타벅스 |
3 | 국기원사거리 | 강남구 | 서울특별시 강남구 테헤란로 125 (역삼동) | 37.499517 | 127.031495 | 스타벅스 |
4 | 대치재경빌딩R | 강남구 | 서울특별시 강남구 남부순환로 2947 (대치동) | 37.494668 | 127.062583 | 스타벅스 |
... | ... | ... | ... | ... | ... | ... |
602 | 사가정역 | 중랑구 | 서울특별시 중랑구 면목로 310 | 37.579594 | 127.087966 | 스타벅스 |
603 | 상봉역 | 중랑구 | 서울특별시 중랑구 망우로 307 (상봉동) | 37.596890 | 127.086470 | 스타벅스 |
604 | 묵동 | 중랑구 | 서울특별시 중랑구 동일로 952 (묵동, 로프트원 태릉입구역) 1층 | 37.615368 | 127.076633 | 스타벅스 |
605 | 양원역 | 중랑구 | 서울특별시 중랑구 양원역로10길 3 (망우동) | 37.606654 | 127.106360 | 스타벅스 |
606 | 중화역 | 중랑구 | 서울특별시 중랑구 봉화산로 35 | 37.601709 | 127.078411 | 스타벅스 |
607 rows × 6 columns
스타벅스와 이디야 데이터는 동일한 형식의 데이터 프레임입니다. 매장명, 구, 주소, 위도, 경도 데이터를 갖고 있고, 방금 분석을 위해 '구분' 컬럼을 만들어 주었습니다.
스타벅스와 이디야 데이터를 합쳐줍니다.
combined_df = pd.concat([df_starbucks, df_ediya])
combined_df
store | 구 | addr | lat | lng | 구분 | |
---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 강남구 | 서울특별시 강남구 언주로 425 (역삼동) | 37.501087 | 127.043069 | 스타벅스 |
1 | 논현역사거리 | 강남구 | 서울특별시 강남구 강남대로 538 (논현동) | 37.510178 | 127.022223 | 스타벅스 |
2 | 신사역성일빌딩 | 강남구 | 서울특별시 강남구 강남대로 584 (논현동) | 37.513931 | 127.020606 | 스타벅스 |
3 | 국기원사거리 | 강남구 | 서울특별시 강남구 테헤란로 125 (역삼동) | 37.499517 | 127.031495 | 스타벅스 |
4 | 대치재경빌딩R | 강남구 | 서울특별시 강남구 남부순환로 2947 (대치동) | 37.494668 | 127.062583 | 스타벅스 |
... | ... | ... | ... | ... | ... | ... |
609 | 중랑교차로점 | 중랑구 | 서울 중랑구 동일로 683 (면목동) | 37.591448 | 127.079882 | 이디야 |
610 | 중랑묵동점 | 중랑구 | 서울 중랑구 동일로 932 (묵동, 묵동자이아파트) | 37.613353 | 127.077536 | 이디야 |
611 | 중랑역점 | 중랑구 | 서울 중랑구 망우로 198 (상봉동) | 37.593285 | 127.074889 | 이디야 |
612 | 중화동점 | 중랑구 | 서울 중랑구 동일로129길 1 (중화동) | 37.599384 | 127.079543 | 이디야 |
613 | 화랑대역점 | 중랑구 | 서울 중랑구 신내로25가길 2 (묵동, 현동학당) | 37.619540 | 127.084137 | 이디야 |
1221 rows × 6 columns
combined_df.reset_index(drop=True, inplace=True)
combined_df
store | 구 | addr | lat | lng | 구분 | |
---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 강남구 | 서울특별시 강남구 언주로 425 (역삼동) | 37.501087 | 127.043069 | 스타벅스 |
1 | 논현역사거리 | 강남구 | 서울특별시 강남구 강남대로 538 (논현동) | 37.510178 | 127.022223 | 스타벅스 |
2 | 신사역성일빌딩 | 강남구 | 서울특별시 강남구 강남대로 584 (논현동) | 37.513931 | 127.020606 | 스타벅스 |
3 | 국기원사거리 | 강남구 | 서울특별시 강남구 테헤란로 125 (역삼동) | 37.499517 | 127.031495 | 스타벅스 |
4 | 대치재경빌딩R | 강남구 | 서울특별시 강남구 남부순환로 2947 (대치동) | 37.494668 | 127.062583 | 스타벅스 |
... | ... | ... | ... | ... | ... | ... |
1216 | 중랑교차로점 | 중랑구 | 서울 중랑구 동일로 683 (면목동) | 37.591448 | 127.079882 | 이디야 |
1217 | 중랑묵동점 | 중랑구 | 서울 중랑구 동일로 932 (묵동, 묵동자이아파트) | 37.613353 | 127.077536 | 이디야 |
1218 | 중랑역점 | 중랑구 | 서울 중랑구 망우로 198 (상봉동) | 37.593285 | 127.074889 | 이디야 |
1219 | 중화동점 | 중랑구 | 서울 중랑구 동일로129길 1 (중화동) | 37.599384 | 127.079543 | 이디야 |
1220 | 화랑대역점 | 중랑구 | 서울 중랑구 신내로25가길 2 (묵동, 현동학당) | 37.619540 | 127.084137 | 이디야 |
1221 rows × 6 columns
시각화 작업을 위해 필요한 설정을 합니다.
# 폰트 설정
%matplotlib inline
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False
구별로 스타벅스와 이디야 매장수를 보기 위해 countplot을 그려보겠습니다.
def draw_countplot():
plt.figure(figsize=(10, 6))
sns.countplot(data=combined_df, x='구', hue='구분',
order=combined_df['구'].value_counts().index,
palette={'스타벅스': '#104C33', '이디야':'#243C84'})
plt.xticks(rotation=45)
plt.xlabel('구', size=15)
plt.ylabel('매장수', size=15)
plt.title('서울시 구별 스타벅스/이디야 매장수', size=20)
plt.show()
draw_countplot()
구별 매장수가 혹시 구별 인구와 관계가 있는지 궁금해져서 그걸 확인해보기로 했습니다.
구별 인구 데이터는 '서울시 열린데이터 광장'(https://data.seoul.go.kr/dataList/419/S/2/datasetView.do)에서 구했습니다.
# '서울시 열린데이터 광장'(https://data.seoul.go.kr/dataList/419/S/2/datasetView.do)에서 수집한 2022 서울시 구별 주민등록인구
population = pd.read_csv('./data/주민등록인구_20231109120918.csv', header=2)
population
동별(1) | 동별(2) | 소계 | 남자 | 여자 | 소계.1 | 남자.1 | 여자.1 | 소계.2 | 남자.2 | 여자.2 | 소계.3 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 합계 | 종로구 | 152211 | 72980 | 79231 | 141379 | 68395 | 72984 | 10832 | 4585 | 6247 | 1.95 |
1 | 합계 | 중구 | 130785 | 63377 | 67408 | 120437 | 58563 | 61874 | 10348 | 4814 | 5534 | 1.91 |
2 | 합계 | 용산구 | 233284 | 113012 | 120272 | 218650 | 105087 | 113563 | 14634 | 7925 | 6709 | 1.99 |
3 | 합계 | 성동구 | 288234 | 139691 | 148543 | 281000 | 136633 | 144367 | 7234 | 3058 | 4176 | 2.11 |
4 | 합계 | 광진구 | 351252 | 168197 | 183055 | 337416 | 162541 | 174875 | 13836 | 5656 | 8180 | 1.99 |
5 | 합계 | 동대문구 | 353601 | 171903 | 181698 | 336644 | 165755 | 170889 | 16957 | 6148 | 10809 | 1.98 |
6 | 합계 | 중랑구 | 390140 | 191422 | 198718 | 385318 | 189537 | 195781 | 4822 | 1885 | 2937 | 2.06 |
7 | 합계 | 성북구 | 441984 | 211246 | 230738 | 430397 | 206961 | 223436 | 11587 | 4285 | 7302 | 2.18 |
8 | 합계 | 강북구 | 297702 | 144037 | 153665 | 293660 | 142567 | 151093 | 4042 | 1470 | 2572 | 2.03 |
9 | 합계 | 도봉구 | 313989 | 152175 | 161814 | 311694 | 151398 | 160296 | 2295 | 777 | 1518 | 2.25 |
10 | 합계 | 노원구 | 508014 | 244010 | 264004 | 503734 | 242145 | 261589 | 4280 | 1865 | 2415 | 2.32 |
11 | 합계 | 은평구 | 470602 | 224163 | 246439 | 466746 | 222592 | 244154 | 3856 | 1571 | 2285 | 2.18 |
12 | 합계 | 서대문구 | 319554 | 150094 | 169460 | 306337 | 145816 | 160521 | 13217 | 4278 | 8939 | 2.10 |
13 | 합계 | 마포구 | 375585 | 175006 | 200579 | 364638 | 171043 | 193595 | 10947 | 3963 | 6984 | 2.02 |
14 | 합계 | 양천구 | 444010 | 216975 | 227035 | 440881 | 215682 | 225199 | 3129 | 1293 | 1836 | 2.43 |
15 | 합계 | 강서구 | 574638 | 275585 | 299053 | 569166 | 273203 | 295963 | 5472 | 2382 | 3090 | 2.08 |
16 | 합계 | 구로구 | 418418 | 206632 | 211786 | 395315 | 194274 | 201041 | 23103 | 12358 | 10745 | 2.15 |
17 | 합계 | 금천구 | 242818 | 122775 | 120043 | 229642 | 115786 | 113856 | 13176 | 6989 | 6187 | 1.92 |
18 | 합계 | 영등포구 | 398085 | 196264 | 201821 | 375675 | 184660 | 191015 | 22410 | 11604 | 10806 | 1.99 |
19 | 합계 | 동작구 | 390432 | 188080 | 202352 | 380596 | 184030 | 196566 | 9836 | 4050 | 5786 | 2.05 |
20 | 합계 | 관악구 | 501226 | 250687 | 250539 | 486752 | 244748 | 242004 | 14474 | 5939 | 8535 | 1.72 |
21 | 합계 | 서초구 | 408451 | 195168 | 213283 | 404325 | 193159 | 211166 | 4126 | 2009 | 2117 | 2.41 |
22 | 합계 | 강남구 | 534103 | 255363 | 278740 | 529102 | 253072 | 276030 | 5001 | 2291 | 2710 | 2.27 |
23 | 합계 | 송파구 | 664514 | 319743 | 344771 | 658801 | 317180 | 341621 | 5713 | 2563 | 3150 | 2.31 |
24 | 합계 | 강동구 | 464037 | 226975 | 237062 | 460067 | 225221 | 234846 | 3970 | 1754 | 2216 | 2.28 |
분석을 위해 컬럼 이름을 변경하고, 분석에 필요한 컬럼만 선택해 새로 데이터 프레임을 만들어 줍니다.
population.rename(columns={'동별(2)': '구', '소계': '인구', '소계.1': '한국인', '소계.2': '외국인'}, inplace=True)
population = population[['구', '인구', '한국인', '외국인']]
population
구 | 인구 | 한국인 | 외국인 | |
---|---|---|---|---|
0 | 종로구 | 152211 | 141379 | 10832 |
1 | 중구 | 130785 | 120437 | 10348 |
2 | 용산구 | 233284 | 218650 | 14634 |
3 | 성동구 | 288234 | 281000 | 7234 |
4 | 광진구 | 351252 | 337416 | 13836 |
5 | 동대문구 | 353601 | 336644 | 16957 |
6 | 중랑구 | 390140 | 385318 | 4822 |
7 | 성북구 | 441984 | 430397 | 11587 |
8 | 강북구 | 297702 | 293660 | 4042 |
9 | 도봉구 | 313989 | 311694 | 2295 |
10 | 노원구 | 508014 | 503734 | 4280 |
11 | 은평구 | 470602 | 466746 | 3856 |
12 | 서대문구 | 319554 | 306337 | 13217 |
13 | 마포구 | 375585 | 364638 | 10947 |
14 | 양천구 | 444010 | 440881 | 3129 |
15 | 강서구 | 574638 | 569166 | 5472 |
16 | 구로구 | 418418 | 395315 | 23103 |
17 | 금천구 | 242818 | 229642 | 13176 |
18 | 영등포구 | 398085 | 375675 | 22410 |
19 | 동작구 | 390432 | 380596 | 9836 |
20 | 관악구 | 501226 | 486752 | 14474 |
21 | 서초구 | 408451 | 404325 | 4126 |
22 | 강남구 | 534103 | 529102 | 5001 |
23 | 송파구 | 664514 | 658801 | 5713 |
24 | 강동구 | 464037 | 460067 | 3970 |
population.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 25 entries, 0 to 24
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 구 25 non-null object
1 인구 25 non-null int64
2 한국인 25 non-null int64
3 외국인 25 non-null int64
dtypes: int64(3), object(1)
memory usage: 928.0+ bytes
구별 인구 순으로 정렬했습니다. 송파구, 강서구, 강남구의 인구가 가장 많습니다. 중구, 종로구가 인구가 가장 적습니다.
population.sort_values(by='인구', ascending=False)
구 | 인구 | 한국인 | 외국인 | |
---|---|---|---|---|
23 | 송파구 | 664514 | 658801 | 5713 |
15 | 강서구 | 574638 | 569166 | 5472 |
22 | 강남구 | 534103 | 529102 | 5001 |
10 | 노원구 | 508014 | 503734 | 4280 |
20 | 관악구 | 501226 | 486752 | 14474 |
11 | 은평구 | 470602 | 466746 | 3856 |
24 | 강동구 | 464037 | 460067 | 3970 |
14 | 양천구 | 444010 | 440881 | 3129 |
7 | 성북구 | 441984 | 430397 | 11587 |
16 | 구로구 | 418418 | 395315 | 23103 |
21 | 서초구 | 408451 | 404325 | 4126 |
18 | 영등포구 | 398085 | 375675 | 22410 |
19 | 동작구 | 390432 | 380596 | 9836 |
6 | 중랑구 | 390140 | 385318 | 4822 |
13 | 마포구 | 375585 | 364638 | 10947 |
5 | 동대문구 | 353601 | 336644 | 16957 |
4 | 광진구 | 351252 | 337416 | 13836 |
12 | 서대문구 | 319554 | 306337 | 13217 |
9 | 도봉구 | 313989 | 311694 | 2295 |
8 | 강북구 | 297702 | 293660 | 4042 |
3 | 성동구 | 288234 | 281000 | 7234 |
17 | 금천구 | 242818 | 229642 | 13176 |
2 | 용산구 | 233284 | 218650 | 14634 |
0 | 종로구 | 152211 | 141379 | 10832 |
1 | 중구 | 130785 | 120437 | 10348 |
좀 전에 그렸던 countplot과 인구를 하나의 그래프에 나타내도록 하겠습니다.
def drawGraph_with_pop():
plt.figure(figsize=(14, 8))
ax1 = sns.countplot(data=combined_df, x='구', hue='구분',
order=combined_df['구'].value_counts().index,
palette={'스타벅스': '#104C33', '이디야':'#243C84'})
plt.xticks(rotation=45)
ax2 = ax1.twinx()
# combined_df의 x축과 인구 데이터의 '구' 순서를 일치시킵니다.
ordered_population = population.set_index('구').loc[combined_df['구'].value_counts().index].reset_index()
# 재정렬된 인구 데이터를 사용해 선 그래프를 그립니다.
sns.lineplot(data=ordered_population, x='구', y='인구', sort=False, ax=ax2, color='black', marker="s")
plt.xlabel('구', size=15)
ax1.set_ylabel('매장수', size=15)
ax2.set_ylabel('인구수', size=15)
plt.title('서울시 구별 스타벅스/이디야 매장수와 구별 인구', size=20)
ax1.legend(title='구분', loc='upper left')
ax2.legend(['인구'], loc='upper right')
plt.grid(True)
plt.show()
drawGraph_with_pop()
구별로 상이한 스타벅스와 이디야 매장수가 인구와 관련성이 있지 않을까 생각해 '구별 주민등록 인구' 데이터를 함께 살펴봤지만, 이와는 상관성이 높지 않아 보입니다. 주민등록인구보다는 흔히 말하는 유동인구와 관련성이 더 높을 것 같습니다. 이를 위해선 유동인구 데이터가 필요한데, 이건 여기선 다루지 않겠습니다.
스타벅스와 이디야의 위경도 정보를 이용해 각각을 지도에 나타내 보겠습니다.
def draw_folium_Graph():
geo_path = './data/02. skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))
seoul = folium.Map(
location=(37.5502, 126.982),
zoom_start=12,
tiles='cartodbpositron'
)
pop = population.set_index('구')
folium.Choropleth(
geo_data=geo_str,
data=pop['인구'],
columns=[pop.index, pop['인구']],
key_on='feature.id',
fill_color='RdPu',
fill_opacity=0.4,
line_opacity=0.4,
legend_name='구별 인구'
).add_to(seoul)
for _, row in combined_df.iterrows():
folium.Marker(
location=(row['lat'], row['lng']),
popup= row['store'],
tooltip= row['구분'],
icon=folium.Icon(
icon_color= '#104C33' if row['구분'] == '스타벅스' else '#243C84',
icon='star' if row['구분'] == '스타벅스' else 'mug-saucer',
prefix='fa'
)
).add_to(seoul)
return seoul
draw_folium_Graph()
이번엔 직접 스타벅스와 이디야 매장이 얼마나 가까이 위치해 있는지 거리를 계산해 보겠습니다.
haversine 모듈을 이용하면 두 지점 사이의 거리를 계산할 수 있습니다. 시험삼아 haversine 모듈로 이디야 강남YMCA점과 스타벅스 역삼아레나빌딩점의 거리를 계산해 보겠습니다.
# 테스트
ediya1 = (37.509943, 127.035702) # 이디야 강남YMCA점
star1 = (37.501087, 127.043069) # 스타벅스 역삼아레나빌딩
haversine(ediya1, star1) # 킬로미터 단위로 계산된 거리를 반환
1.17983920649527
구글 지도를 통해 두 지점의 거리를 계산한 결과는 1.2km입니다. 구글 지도와 오차는 30m정도입니다. 사용하기에 큰 무리가 없을 것 같습니다.
그러면 가장 가까운 상대 브랜드 매장과의 거리를 구하는 함수를 정의하겠습니다.
def get_distance(first_df, second_df):
first_location = []
for _, row in first_df.iterrows():
first_location.append((row['lat'], row['lng']))
second_location = []
for _, row in second_df.iterrows():
second_location.append((row['lat'], row['lng']))
first_dist = []
second_dist = []
# 가장 가까운 이디야 매장과의 거리를 구함(m 단위)
for first in tqdm(first_location):
min_first = np.inf
for second in second_location:
distance = haversine(first, second, unit=Unit.METERS)
if distance < min_first:
min_first = distance
first_dist.append(int(min_first))
# 가장 가까운 스타벅스 매장과의 거리를 구함(m 단위)
for second in tqdm(second_location):
min_second = np.inf
for first in first_location:
distance = haversine(second, first, unit=Unit.METERS)
if distance < min_second:
min_second = distance
second_dist.append(int(min_second))
result_first = first_df.copy()
result_second = second_df.copy()
result_first['가까운 상대 매장(m)'] = first_dist
result_second['가까운 상대 매장(m)'] = second_dist
return result_first, result_second
가장 가까운 상대 브랜드 매장까지의 데이터가 추가된 새로운 데이터 프레임을 결과로 반환받습니다.
tmp_star, tmp_edy = get_distance(df_starbucks, df_ediya)
tmp_star
store | 구 | addr | lat | lng | 구분 | 가까운 상대 매장(m) | |
---|---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 강남구 | 서울특별시 강남구 언주로 425 (역삼동) | 37.501087 | 127.043069 | 스타벅스 | 86 |
1 | 논현역사거리 | 강남구 | 서울특별시 강남구 강남대로 538 (논현동) | 37.510178 | 127.022223 | 스타벅스 | 207 |
2 | 신사역성일빌딩 | 강남구 | 서울특별시 강남구 강남대로 584 (논현동) | 37.513931 | 127.020606 | 스타벅스 | 121 |
3 | 국기원사거리 | 강남구 | 서울특별시 강남구 테헤란로 125 (역삼동) | 37.499517 | 127.031495 | 스타벅스 | 415 |
4 | 대치재경빌딩R | 강남구 | 서울특별시 강남구 남부순환로 2947 (대치동) | 37.494668 | 127.062583 | 스타벅스 | 643 |
... | ... | ... | ... | ... | ... | ... | ... |
602 | 사가정역 | 중랑구 | 서울특별시 중랑구 면목로 310 | 37.579594 | 127.087966 | 스타벅스 | 603 |
603 | 상봉역 | 중랑구 | 서울특별시 중랑구 망우로 307 (상봉동) | 37.596890 | 127.086470 | 스타벅스 | 284 |
604 | 묵동 | 중랑구 | 서울특별시 중랑구 동일로 952 (묵동, 로프트원 태릉입구역) 1층 | 37.615368 | 127.076633 | 스타벅스 | 237 |
605 | 양원역 | 중랑구 | 서울특별시 중랑구 양원역로10길 3 (망우동) | 37.606654 | 127.106360 | 스타벅스 | 98 |
606 | 중화역 | 중랑구 | 서울특별시 중랑구 봉화산로 35 | 37.601709 | 127.078411 | 스타벅스 | 277 |
607 rows × 7 columns
tmp_star[tmp_star['가까운 상대 매장(m)'] < 500]
store | 구 | addr | lat | lng | 구분 | 가까운 상대 매장(m) | |
---|---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 강남구 | 서울특별시 강남구 언주로 425 (역삼동) | 37.501087 | 127.043069 | 스타벅스 | 86 |
1 | 논현역사거리 | 강남구 | 서울특별시 강남구 강남대로 538 (논현동) | 37.510178 | 127.022223 | 스타벅스 | 207 |
2 | 신사역성일빌딩 | 강남구 | 서울특별시 강남구 강남대로 584 (논현동) | 37.513931 | 127.020606 | 스타벅스 | 121 |
3 | 국기원사거리 | 강남구 | 서울특별시 강남구 테헤란로 125 (역삼동) | 37.499517 | 127.031495 | 스타벅스 | 415 |
6 | 압구정윤성빌딩 | 강남구 | 서울특별시 강남구 논현로 834 (신사동) | 37.522793 | 127.028601 | 스타벅스 | 384 |
... | ... | ... | ... | ... | ... | ... | ... |
601 | 중랑구청 | 중랑구 | 서울특별시 중랑구 신내로 72 | 37.605389 | 127.095756 | 스타벅스 | 263 |
603 | 상봉역 | 중랑구 | 서울특별시 중랑구 망우로 307 (상봉동) | 37.596890 | 127.086470 | 스타벅스 | 284 |
604 | 묵동 | 중랑구 | 서울특별시 중랑구 동일로 952 (묵동, 로프트원 태릉입구역) 1층 | 37.615368 | 127.076633 | 스타벅스 | 237 |
605 | 양원역 | 중랑구 | 서울특별시 중랑구 양원역로10길 3 (망우동) | 37.606654 | 127.106360 | 스타벅스 | 98 |
606 | 중화역 | 중랑구 | 서울특별시 중랑구 봉화산로 35 | 37.601709 | 127.078411 | 스타벅스 | 277 |
493 rows × 7 columns
스타벅스 전체 607개 매장 중 493개가 500m 이내 이디야 매장이 위치합니다.
tmp_star.describe()
lat | lng | 가까운 상대 매장(m) | |
---|---|---|---|
count | 607.000000 | 607.000000 | 607.000000 |
mean | 37.539477 | 126.991063 | 318.614498 |
std | 0.041383 | 0.076504 | 275.155347 |
min | 37.447323 | 126.806080 | 3.000000 |
25% | 37.506984 | 126.931466 | 137.000000 |
50% | 37.537817 | 126.991782 | 253.000000 |
75% | 37.565345 | 127.044916 | 414.500000 |
max | 37.665312 | 127.174104 | 3317.000000 |
가까운 이디야 매장까지의 평균거리는 318m입니다
tmp_edy
store | 구 | addr | lat | lng | 구분 | 가까운 상대 매장(m) | |
---|---|---|---|---|---|---|---|
0 | 강남YMCA점 | 강남구 | 서울 강남구 논현동 230-2 | 37.509943 | 127.035702 | 이디야 | 250 |
1 | 강남구청역아이티웨딩점 | 강남구 | 서울 강남구 학동로 338 (논현동, 강남파라곤) | 37.516542 | 127.040160 | 이디야 | 95 |
2 | 강남논현학동점 | 강남구 | 서울 강남구 논현로131길 28 (논현동) | 37.514080 | 127.028106 | 이디야 | 239 |
3 | 강남대치점 | 강남구 | 서울 강남구 역삼로 415 (대치동, 성진빌딩) | 37.501339 | 127.052429 | 이디야 | 291 |
4 | 강남도산점 | 강남구 | 서울 강남구 도산대로37길 20 (신사동) | 37.501339 | 127.052429 | 이디야 | 291 |
... | ... | ... | ... | ... | ... | ... | ... |
609 | 중랑교차로점 | 중랑구 | 서울 중랑구 동일로 683 (면목동) | 37.591448 | 127.079882 | 이디야 | 486 |
610 | 중랑묵동점 | 중랑구 | 서울 중랑구 동일로 932 (묵동, 묵동자이아파트) | 37.613353 | 127.077536 | 이디야 | 237 |
611 | 중랑역점 | 중랑구 | 서울 중랑구 망우로 198 (상봉동) | 37.593285 | 127.074889 | 이디야 | 31 |
612 | 중화동점 | 중랑구 | 서울 중랑구 동일로129길 1 (중화동) | 37.599384 | 127.079543 | 이디야 | 277 |
613 | 화랑대역점 | 중랑구 | 서울 중랑구 신내로25가길 2 (묵동, 현동학당) | 37.619540 | 127.084137 | 이디야 | 424 |
614 rows × 7 columns
tmp_edy[tmp_edy['가까운 상대 매장(m)'] < 500]
store | 구 | addr | lat | lng | 구분 | 가까운 상대 매장(m) | |
---|---|---|---|---|---|---|---|
0 | 강남YMCA점 | 강남구 | 서울 강남구 논현동 230-2 | 37.509943 | 127.035702 | 이디야 | 250 |
1 | 강남구청역아이티웨딩점 | 강남구 | 서울 강남구 학동로 338 (논현동, 강남파라곤) | 37.516542 | 127.040160 | 이디야 | 95 |
2 | 강남논현학동점 | 강남구 | 서울 강남구 논현로131길 28 (논현동) | 37.514080 | 127.028106 | 이디야 | 239 |
3 | 강남대치점 | 강남구 | 서울 강남구 역삼로 415 (대치동, 성진빌딩) | 37.501339 | 127.052429 | 이디야 | 291 |
4 | 강남도산점 | 강남구 | 서울 강남구 도산대로37길 20 (신사동) | 37.501339 | 127.052429 | 이디야 | 291 |
... | ... | ... | ... | ... | ... | ... | ... |
609 | 중랑교차로점 | 중랑구 | 서울 중랑구 동일로 683 (면목동) | 37.591448 | 127.079882 | 이디야 | 486 |
610 | 중랑묵동점 | 중랑구 | 서울 중랑구 동일로 932 (묵동, 묵동자이아파트) | 37.613353 | 127.077536 | 이디야 | 237 |
611 | 중랑역점 | 중랑구 | 서울 중랑구 망우로 198 (상봉동) | 37.593285 | 127.074889 | 이디야 | 31 |
612 | 중화동점 | 중랑구 | 서울 중랑구 동일로129길 1 (중화동) | 37.599384 | 127.079543 | 이디야 | 277 |
613 | 화랑대역점 | 중랑구 | 서울 중랑구 신내로25가길 2 (묵동, 현동학당) | 37.619540 | 127.084137 | 이디야 | 424 |
437 rows × 7 columns
이디야 전체 614개 매장 중 437개가 500m 이내 스타벅스 매장이 위치합니다.
tmp_edy.describe()
lat | lng | 가까운 상대 매장(m) | |
---|---|---|---|
count | 614.000000 | 614.000000 | 614.000000 |
mean | 37.547512 | 126.990863 | 401.363192 |
std | 0.051171 | 0.086173 | 380.282273 |
min | 37.434112 | 126.806994 | 3.000000 |
25% | 37.505157 | 126.916598 | 131.000000 |
50% | 37.547035 | 127.005689 | 283.500000 |
75% | 37.579345 | 127.057496 | 585.500000 |
max | 37.687538 | 127.175934 | 2471.000000 |
가장 가까운 스타벅스 매장까지의 평균거리는 401m입니다. 스타벅스에 비해 상대 브랜드까지의 평균거리가 83m 더 멉니다.
시각화를 위해 다시 두 데이터 프레임을 합쳐주겠습니다.
combined_distance = pd.concat([tmp_star, tmp_edy])
combined_distance.reset_index(drop=True, inplace=True)
combined_distance
store | 구 | addr | lat | lng | 구분 | 가까운 상대 매장(m) | |
---|---|---|---|---|---|---|---|
0 | 역삼아레나빌딩 | 강남구 | 서울특별시 강남구 언주로 425 (역삼동) | 37.501087 | 127.043069 | 스타벅스 | 86 |
1 | 논현역사거리 | 강남구 | 서울특별시 강남구 강남대로 538 (논현동) | 37.510178 | 127.022223 | 스타벅스 | 207 |
2 | 신사역성일빌딩 | 강남구 | 서울특별시 강남구 강남대로 584 (논현동) | 37.513931 | 127.020606 | 스타벅스 | 121 |
3 | 국기원사거리 | 강남구 | 서울특별시 강남구 테헤란로 125 (역삼동) | 37.499517 | 127.031495 | 스타벅스 | 415 |
4 | 대치재경빌딩R | 강남구 | 서울특별시 강남구 남부순환로 2947 (대치동) | 37.494668 | 127.062583 | 스타벅스 | 643 |
... | ... | ... | ... | ... | ... | ... | ... |
1216 | 중랑교차로점 | 중랑구 | 서울 중랑구 동일로 683 (면목동) | 37.591448 | 127.079882 | 이디야 | 486 |
1217 | 중랑묵동점 | 중랑구 | 서울 중랑구 동일로 932 (묵동, 묵동자이아파트) | 37.613353 | 127.077536 | 이디야 | 237 |
1218 | 중랑역점 | 중랑구 | 서울 중랑구 망우로 198 (상봉동) | 37.593285 | 127.074889 | 이디야 | 31 |
1219 | 중화동점 | 중랑구 | 서울 중랑구 동일로129길 1 (중화동) | 37.599384 | 127.079543 | 이디야 | 277 |
1220 | 화랑대역점 | 중랑구 | 서울 중랑구 신내로25가길 2 (묵동, 현동학당) | 37.619540 | 127.084137 | 이디야 | 424 |
1221 rows × 7 columns
combined_distance.describe()
lat | lng | 가까운 상대 매장(m) | |
---|---|---|---|
count | 1221.000000 | 1221.000000 | 1221.000000 |
mean | 37.543517 | 126.990962 | 360.226044 |
std | 0.046717 | 0.081477 | 334.638758 |
min | 37.434112 | 126.806080 | 3.000000 |
25% | 37.505760 | 126.922130 | 133.000000 |
50% | 37.541456 | 126.999650 | 261.000000 |
75% | 37.570214 | 127.051536 | 478.000000 |
max | 37.687538 | 127.175934 | 3317.000000 |
def draw_distance_by_boxplot():
plt.figure(figsize=(12, 8))
sns.boxplot(data=combined_distance, x='구', y='가까운 상대 매장(m)',
hue='구분', palette={'스타벅스': '#104C33', '이디야':'#243C84'})
plt.xticks(rotation=45)
plt.title('가장 가까운 상대 브랜드 매장까지의 거리(스타벅스/이디야)', size=20)
plt.grid(True)
plt.show()
draw_distance_by_boxplot()
'이디야가 스타벅스 매장이 위치하는 곳에 매장을 위치시키는 것이 아니냐는 의심'은 스타벅스 입장에선 근거가 있는 걸로 보입니다. 하지만 이디야 입장에선 구별 매장 분포도 스타벅스와는 다른 양상을 보이고, 가까운 스타벅스 매장과의 거리가 500m 이상인 매장도 다수 존재한다고 말할 수 있습니다.
haversine 모듈을 통해 상대 브랜드 매장까지의 거리를 계산한 결과를 보면, 스타벅스와 이디야 모두 서울에 위치한 600여개 매장 중 400개 이상의 매장이 상대 브랜드 매장까지의 거리가 400m 이내 라는 걸 알 수 있습니다. 하지만, 두 브랜드가 같은 업종인 점을 생각하면 입점을 위해 고려할 요소들이 유사할 수 있기 때문에 상대 브랜드 매장까지의 거리가 크지 않은 것이라고 판단할 수도 있습니다.
구별 매장 분포에서 스타벅스와 이디야 두 브랜드가 상당히 다른 분포를 보이는 것을 생각하면, 두 브랜드가 고려하는 입점 요소에는 차이가 있다고 생각됩니다. 스타벅스와 이디야 모두 구별 매장 수에 차이가 있지만 이디야는 비교적 고른 분포를 보인 반면, 스타벅스는 일부 지역에 매장이 편중된 양상을 보였습니다.
본문에서 데이터로 확인하진 않았지만, 스타벅스는 유동인구가 많은 지역에 집중적으로 매장을 입점시켜 매출을 극대화하는 방향을 추구한 것 같습니다. 반면, 이디야는 개인점주가 중심이기 때문에 임대료가 비싼 지역에 입점하는데 한계가 있습니다. 또, 점주의 생활반경 내에 매장을 구하는게 보통이기도 합니다. 이런 요소가 스타벅스와 이디야 매장이 구별로 상이한 분포를 보이는 이유일 것 같습니다.