상가업소정보로 프랜차이즈 입점분석
배스킨라빈스 & 던킨도너츠 프랜차이즈 매장의 밀집도를 지도를 통해 표시하고, 이를 위해 데이터 전처리 과정을 진행한다.
다루는 내용
- 데이터 요약하기
- 공공데이터를 활용해 텍스트 데이터 정제하고 원하는 정보 찾아내기
- 문자열에서 원하는 텍스트 추출하기
- 문자열을 활용한 다양한 분석 방법과 위치 정보 사용하기
- folium을 통한 위경도 데이터 시각화 이해하기
- folium을 통해 지도에 분석한 내용을 표현하기 - CircleMarker와 MarkerCluster 그리기
데이터셋
출처 : https://www.inflearn.com/course/%EA%B3%B5%EA%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A1%9C-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%EC%84%9D-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0¶
본격적인 분석에 앞서
1. 필요한 라이브러리 불러오기
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
2. 시각화를 위한 한글 폰트 설정하기
# 윈도우 사용자이기 때문에 "Malgun Gothic"으로 설정해준다.
plt.rc("font", family="Malgun Gothic")
plt.rc("axes", unicode_minus=False)
# 폰트가 선명하게 보이도록 설정
from IPython.display import set_matplotlib_formats
%config InlineBackend.figure_format = 'retina'
# 한글폰트와 마이너스 폰트 설정 확인
plt.title("한글폰트 설정")
plt.plot([-4, -6, 1, 2, 0, 3])
#한글폰트의 선명도를 높이기 위해 바로 위의 셀의 코드를 작성해 적용해준다.
[<matplotlib.lines.Line2D at 0x29ead5b25b0>]
3. 데이터 불러오기
# 파일을 불러오기 위해 pd.reda_csv()를 사용
# 매번 데이터를 불러오는 것은 복잡하기 때문에 df라는 변수에 담아준다.
df = pd.read_csv("C:/Users/yobin/Downloads/상가업소정보_201912_01.csv", sep='|')
df.head()
상가업소번호 | 상호명 | 지점명 | 상권업종대분류코드 | 상권업종대분류명 | 상권업종중분류코드 | 상권업종중분류명 | 상권업종소분류코드 | 상권업종소분류명 | 표준산업분류코드 | ... | 건물관리번호 | 건물명 | 도로명주소 | 구우편번호 | 신우편번호 | 동정보 | 층정보 | 호정보 | 경도 | 위도 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 19905471 | 와라와라호프 | NaN | Q | 음식 | Q09 | 유흥주점 | Q09A01 | 호프/맥주 | I56219 | ... | 1168010600106040000014378 | 대치상가 | 서울특별시 강남구 남부순환로 2933 | 135280 | 6280.0 | NaN | 1 | NaN | 127.061026 | 37.493922 |
1 | 19911397 | 커피빈코리아선릉로93길점 | 코리아선릉로93길점 | Q | 음식 | Q12 | 커피점/카페 | Q12A01 | 커피전문점/카페/다방 | I56220 | ... | 1168010100106960042022041 | NaN | 서울특별시 강남구 선릉로93길 6 | 135080 | 6149.0 | NaN | 1 | NaN | 127.047883 | 37.505675 |
2 | 19911801 | 프로포즈 | NaN | Q | 음식 | Q09 | 유흥주점 | Q09A01 | 호프/맥주 | I56219 | ... | 1154510200101620001017748 | NaN | 서울특별시 금천구 가산로 34-6 | 153010 | 8545.0 | NaN | 1 | NaN | 126.899220 | 37.471711 |
3 | 19912201 | 싱싱커피&토스트 | NaN | Q | 음식 | Q07 | 패스트푸드 | Q07A10 | 토스트전문 | I56192 | ... | 2653010400105780000002037 | 산업용품유통상가 | 부산광역시 사상구 괘감로 37 | 617726 | 46977.0 | NaN | 1 | 26 | 128.980455 | 35.159774 |
4 | 19932756 | 가락사우나내스낵 | NaN | F | 생활서비스 | F09 | 대중목욕탕/휴게 | F09A02 | 사우나/증기탕/온천 | S96121 | ... | 1171010500102560005010490 | NaN | 서울특별시 송파구 가락로 71 | 138846 | 5690.0 | NaN | 1 | NaN | 127.104071 | 37.500249 |
5 rows × 39 columns
3-1. 데이터 크기 보기
# shape 를 통해 불러온 csv 파일의 크기를 확인
df.shape
(573680, 39)
3-2. info 보기
# info 를 사용하면 데이터의 전체적인 정보, 데이터의 사이즈, 타입, 메모리 사용량 등 확인 가능하다.
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 573680 entries, 0 to 573679
Data columns (total 39 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 상가업소번호 573680 non-null int64
1 상호명 573679 non-null object
2 지점명 76674 non-null object
3 상권업종대분류코드 573680 non-null object
4 상권업종대분류명 573680 non-null object
5 상권업종중분류코드 573680 non-null object
6 상권업종중분류명 573680 non-null object
7 상권업종소분류코드 573680 non-null object
8 상권업종소분류명 573680 non-null object
9 표준산업분류코드 539290 non-null object
10 표준산업분류명 539290 non-null object
11 시도코드 573680 non-null int64
12 시도명 573680 non-null object
13 시군구코드 573680 non-null int64
14 시군구명 573680 non-null object
15 행정동코드 573680 non-null int64
16 행정동명 573680 non-null object
17 법정동코드 573680 non-null int64
18 법정동명 573680 non-null object
19 지번코드 573680 non-null int64
20 대지구분코드 573680 non-null int64
21 대지구분명 573680 non-null object
22 지번본번지 573680 non-null int64
23 지번부번지 474924 non-null float64
24 지번주소 573680 non-null object
25 도로명코드 573680 non-null int64
26 도로명 573680 non-null object
27 건물본번지 573680 non-null int64
28 건물부번지 71988 non-null float64
29 건물관리번호 573680 non-null object
30 건물명 265608 non-null object
31 도로명주소 573680 non-null object
32 구우편번호 573680 non-null int64
33 신우편번호 573671 non-null float64
34 동정보 50856 non-null object
35 층정보 347127 non-null object
36 호정보 85266 non-null object
37 경도 573680 non-null float64
38 위도 573680 non-null float64
dtypes: float64(5), int64(11), object(23)
memory usage: 170.7+ MB
3-3. 결측치 확인
# isnull() - 데이터의 결측치
# 결측치는 True로 값이 있다면 False로 표시되는데 True 는 1과 같기 때문에
# True 값을 sum()을 사용해서 더하게 되면 합계를 볼 수 있다.
# mean()을 사용하면 결측치의 비율을 볼 수 있다.
df.isnull()
상가업소번호 | 상호명 | 지점명 | 상권업종대분류코드 | 상권업종대분류명 | 상권업종중분류코드 | 상권업종중분류명 | 상권업종소분류코드 | 상권업종소분류명 | 표준산업분류코드 | ... | 건물관리번호 | 건물명 | 도로명주소 | 구우편번호 | 신우편번호 | 동정보 | 층정보 | 호정보 | 경도 | 위도 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | False | False | True | False | False | False | False | False | False | False | ... | False | False | False | False | False | True | False | True | False | False |
1 | False | False | False | False | False | False | False | False | False | False | ... | False | True | False | False | False | True | False | True | False | False |
2 | False | False | True | False | False | False | False | False | False | False | ... | False | True | False | False | False | True | False | True | False | False |
3 | False | False | True | False | False | False | False | False | False | False | ... | False | False | False | False | False | True | False | False | False | False |
4 | False | False | True | False | False | False | False | False | False | False | ... | False | True | False | False | False | True | False | True | False | False |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
573675 | False | False | True | False | False | False | False | False | False | False | ... | False | True | False | False | False | True | True | True | False | False |
573676 | False | False | True | False | False | False | False | False | False | False | ... | False | False | False | False | False | True | False | True | False | False |
573677 | False | False | True | False | False | False | False | False | False | False | ... | False | False | False | False | False | True | False | True | False | False |
573678 | False | False | True | False | False | False | False | False | False | False | ... | False | False | False | False | False | True | False | True | False | False |
573679 | False | False | True | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | True | True | False | False |
573680 rows × 39 columns
df.isnull().sum()
상가업소번호 0
상호명 1
지점명 497006
상권업종대분류코드 0
상권업종대분류명 0
상권업종중분류코드 0
상권업종중분류명 0
상권업종소분류코드 0
상권업종소분류명 0
표준산업분류코드 34390
표준산업분류명 34390
시도코드 0
시도명 0
시군구코드 0
시군구명 0
행정동코드 0
행정동명 0
법정동코드 0
법정동명 0
지번코드 0
대지구분코드 0
대지구분명 0
지번본번지 0
지번부번지 98756
지번주소 0
도로명코드 0
도로명 0
건물본번지 0
건물부번지 501692
건물관리번호 0
건물명 308072
도로명주소 0
구우편번호 0
신우편번호 9
동정보 522824
층정보 226553
호정보 488414
경도 0
위도 0
dtype: int64
df.isnull().mean()
상가업소번호 0.000000
상호명 0.000002
지점명 0.866347
상권업종대분류코드 0.000000
상권업종대분류명 0.000000
상권업종중분류코드 0.000000
상권업종중분류명 0.000000
상권업종소분류코드 0.000000
상권업종소분류명 0.000000
표준산업분류코드 0.059946
표준산업분류명 0.059946
시도코드 0.000000
시도명 0.000000
시군구코드 0.000000
시군구명 0.000000
행정동코드 0.000000
행정동명 0.000000
법정동코드 0.000000
법정동명 0.000000
지번코드 0.000000
대지구분코드 0.000000
대지구분명 0.000000
지번본번지 0.000000
지번부번지 0.172145
지번주소 0.000000
도로명코드 0.000000
도로명 0.000000
건물본번지 0.000000
건물부번지 0.874515
건물관리번호 0.000000
건물명 0.537010
도로명주소 0.000000
구우편번호 0.000000
신우편번호 0.000016
동정보 0.911351
층정보 0.394912
호정보 0.851370
경도 0.000000
위도 0.000000
dtype: float64
df.isnull().mean().plot.barh(figsize=(7,9))
<AxesSubplot:>
3-4. 사용하지 않는 컬럼 제거하기
# 사용할 컬럼만 따로 모아 사용하는 방식을 이용해 사용하지 않는 컬럼을 제거한다.
columns = ['상호명', '상권업종대분류명', '상권업종중분류명', '상권업종소분류명',
'시도명', '시군구명', '행정동명', '법정동명', '도로명주소',
'경도', '위도']
df= df[columns].copy()
df.shape
(573680, 11)
# 제거 후 메모리 사용량 보기
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 573680 entries, 0 to 573679
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 상호명 573679 non-null object
1 상권업종대분류명 573680 non-null object
2 상권업종중분류명 573680 non-null object
3 상권업종소분류명 573680 non-null object
4 시도명 573680 non-null object
5 시군구명 573680 non-null object
6 행정동명 573680 non-null object
7 법정동명 573680 non-null object
8 도로명주소 573680 non-null object
9 경도 573680 non-null float64
10 위도 573680 non-null float64
dtypes: float64(2), object(9)
memory usage: 48.1+ MB
4. 색인으로 서브셋 가져오기
4-1. 서울만 따로 보기
# 시도명이 서울로 시작하는 데이터만 추출하여 df_seoul 이라는 변수에 결과 저장한다.
# 새로운 변수에 데이터프레임을 할당할 때 copy()를 사용해 원본 데이터가 손상되는 것을 사전에 방지한다.
df_seoul = df[df["시도명"] == "서울특별시"].copy()
print(df_seoul.shape)
df_seoul.head()
(407376, 11)
상호명 | 상권업종대분류명 | 상권업종중분류명 | 상권업종소분류명 | 시도명 | 시군구명 | 행정동명 | 법정동명 | 도로명주소 | 경도 | 위도 | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 와라와라호프 | 음식 | 유흥주점 | 호프/맥주 | 서울특별시 | 강남구 | 대치1동 | 대치동 | 서울특별시 강남구 남부순환로 2933 | 127.061026 | 37.493922 |
1 | 커피빈코리아선릉로93길점 | 음식 | 커피점/카페 | 커피전문점/카페/다방 | 서울특별시 | 강남구 | 역삼1동 | 역삼동 | 서울특별시 강남구 선릉로93길 6 | 127.047883 | 37.505675 |
2 | 프로포즈 | 음식 | 유흥주점 | 호프/맥주 | 서울특별시 | 금천구 | 독산3동 | 독산동 | 서울특별시 금천구 가산로 34-6 | 126.899220 | 37.471711 |
4 | 가락사우나내스낵 | 생활서비스 | 대중목욕탕/휴게 | 사우나/증기탕/온천 | 서울특별시 | 송파구 | 석촌동 | 석촌동 | 서울특별시 송파구 가락로 71 | 127.104071 | 37.500249 |
5 | 초밥왕 | 음식 | 일식/수산물 | 음식점-초밥전문 | 서울특별시 | 송파구 | 잠실6동 | 신천동 | 서울특별시 송파구 올림픽로 293-19 | 127.102490 | 37.515149 |
# unique 를 사용하면 중복을 제거한 시군구명을 가져온 후, shape로 갯수를 출력한다.
df_seoul["시군구명"].unique()
array(['강남구', '금천구', '송파구', '광진구', '강서구', '중구', '서초구', '성북구', '구로구',
'영등포구', '서대문구', '동대문구', '노원구', '동작구', '성동구', '관악구', '강동구', '양천구',
'종로구', '강북구', '은평구', '중랑구', '도봉구', '마포구', '용산구'], dtype=object)
# nunique() = 중복을 제거한 항목의 갯수
df_seoul["시군구명"].nunique()
25
5. 파일로 저장하기
- 전처리한 파일을 저장해 두면 재사용이 가능하다.
df_seoul.to_csv("seoul_open_store.csv" , index = False)
# index 포함하지 않은 데이터셋을 저장하고 싶다면 index = False를 입력한다.
# 저장되었는지 확인
pd.read_csv("seoul_open_store.csv").head()
상호명 | 상권업종대분류명 | 상권업종중분류명 | 상권업종소분류명 | 시도명 | 시군구명 | 행정동명 | 법정동명 | 도로명주소 | 경도 | 위도 | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 와라와라호프 | 음식 | 유흥주점 | 호프/맥주 | 서울특별시 | 강남구 | 대치1동 | 대치동 | 서울특별시 강남구 남부순환로 2933 | 127.061026 | 37.493922 |
1 | 커피빈코리아선릉로93길점 | 음식 | 커피점/카페 | 커피전문점/카페/다방 | 서울특별시 | 강남구 | 역삼1동 | 역삼동 | 서울특별시 강남구 선릉로93길 6 | 127.047883 | 37.505675 |
2 | 프로포즈 | 음식 | 유흥주점 | 호프/맥주 | 서울특별시 | 금천구 | 독산3동 | 독산동 | 서울특별시 금천구 가산로 34-6 | 126.899220 | 37.471711 |
3 | 가락사우나내스낵 | 생활서비스 | 대중목욕탕/휴게 | 사우나/증기탕/온천 | 서울특별시 | 송파구 | 석촌동 | 석촌동 | 서울특별시 송파구 가락로 71 | 127.104071 | 37.500249 |
4 | 초밥왕 | 음식 | 일식/수산물 | 음식점-초밥전문 | 서울특별시 | 송파구 | 잠실6동 | 신천동 | 서울특별시 송파구 올림픽로 293-19 | 127.102490 | 37.515149 |
'Data Analysis > python' 카테고리의 다른 글
[python] jupyter notebook에서 생성한 folium map 티스토리로 불러오기 (2) | 2023.01.26 |
---|---|
[python] 소상공인시장진흥공단 상가업소정보로 프랜차이즈 입점분석 (2) (1) | 2023.01.25 |
[python] 데이터 전처리 ② (0) | 2023.01.14 |
[python] 데이터 전처리 ① : 변수 추출 (0) | 2023.01.12 |
[python] 데이터 프레임 (1) | 2023.01.08 |
댓글