따릉이 데이터로 가장 많은 대여소가 있는 지역은 어디인지,
따릉이를 가장 많이 소유하고 있는 지역은 어디인지 알아보자!
1. 라이브러리 및 한글 폰트 설정
import pandas as pd
import seaborn as sns
import matplotlib
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
font_name = fm.FontProperties(fname = '../NanumBarunGothic.ttf').get_name()
matplotlib.rc('font', family = font_name)
matplotlib.rcParams['axes.unicode_minus'] = False
2. 데이터
http://data.seoul.go.kr/dataList/OA-13252/F/1/datasetView.do
- 위에 공공데이터 포털에서 따릉이 데이터를 가져왔다.
bike_06 = pd.read_csv('data/공공자전거 대여소 정보(21.06월 기준)_1행수정.csv', encoding='cp949')
bike_06
3. 결측치 확인 및 채우기
bike_06.info()
- row = 2467, column = 10
- LCD, QR 컬럼에 NULL값이 존재한다.
- 이 데이터에는 각 대여소에 LCD 따릉이와 QR 따릉이가 없으면 NULL값으로 되어있으므로
- NULL값을 0으로 채웠다.
bike_06.fillna(0, inplace=True)
bike_06['LCD'] = bike_06['LCD'].astype(int) # 데이터 타입 변환
bike_06['QR'] = bike_06['QR'].astype(int)
bike_06.info()
- LCD, QR 컬럼의 NULL값에 0으로 채우고 float 타입을 int 타입으로 변환해주었다.
4. 자치구별 따릉이 대여소 수
bike_06['자치구'].value_counts()
- DataFrame.value_counts()를 이용하여 자치구별 대여소 개수를 알아보면 위와 같다.
Seoul_gu = pd.value_counts(bike_06['자치구'].values, sort = True).head(10)
x = Seoul_gu.plot.bar(grid = True, figsize = (10,8), fontsize = 15, color = '#1BCF1C')
plt.title('<자치구별 따릉이 대여 장소 수>', fontsize = 20)
plt.xlabel('자치구', fontsize = 15)
plt.ylabel('Count', fontsize = 15)
plt.xticks(rotation=0)
plt.annotate('최댓값', xy = (0,184), xytext = (0,160),
fontsize = 14, ha = 'center', color ='red',
bbox=dict(boxstyle='square', color='yellow'), # 상자안에 글자
arrowprops = dict(facecolor='black', width = 1, headwidth=10))
# (문자, xy = 화살표 방향, xytext = 문자, 화살표 위치, arrowprops = 화살표 성격)
for p in x.patches: # bar에 수치 표현
left, bottom, width, height = p.get_bbox().bounds
plt.annotate(f"{int(height)}",(left+width/2, height+3), ha = 'center', size =14, color = 'black')
plt.show()
- Seoul_gu는 자치구별 따릉이 대여소 수 중 Top10을 의미한다.
- 그래프는 plot.bar()를 이용하여 간단하게 그리고 plt.xticks(rotation = 0)을 통해 x축 눈금 레이블을 수정했다.
- plt.annotation()을 통해 최댓값을 표시해주었다.
- plt.annotation(문자, xy = 화살표 방향, xytext = 문자, 화살표 위치, arrowprops = 화살표 성격, 그 외 설정값)
- for문을 통해 각 막대에 수치를 표현해주었다.
- 자치구별로 보면 송파구, 강서구, 강남구가 가장 많은 따릉이 대여소를 가지고 있다.
5. 총 따릉이 수 컬럼 추가
bike_06['총 따릉이 수'] = bike_06['LCD'] + bike_06['QR']
bike_06.iloc[417:427]
- 총 따릉이 수 = LCD + QR
- 총 따릉이 수 컬럼을 추가하면 위와 같은 결과가 나온다.
6. 자치구별 총 따릉이 수 비교
bike_06_total = bike_06.groupby(bike_06['자치구'])[['총 따릉이 수']].sum().sort_values(by='총 따릉이 수' ,ascending=False)
bike_06_total_top10 = bike_06_total.head(n=10)
bike_06_total_top10
x = bike_06_total_top10.plot.bar(grid = True, figsize = (10, 8), fontsize = 15, color = '#1BCF1C')
plt.xticks(rotation = 0)
plt.title('<자치구별 총 따릉이 수>', fontsize = 20)
plt.xlabel('자치구', fontsize = 15)
plt.ylabel('Count', fontsize = 15)
for p in x.patches: # bar에 수치 표현
left, bottom, width, height = p.get_bbox().bounds
plt.annotate(f"{int(height)}",(left+width/2, height+10), ha = 'center', size =14, color = 'black')
plt.show()
- 송파구가 자치구별로 가장 따릉이 대여소가 많은 만큼 따릉이 수도 많다는 것을 확인할 수 있다.
- 따릉이 대여소 Top3에는 송파구, 강서구, 강남구 이였으나
- 따릉이 수 Top3에는 송파구, 강서구, 서초구를 나타낸다.
7. 자치구별 LCD, QR 따릉이수
7-1. LCD, QR 비교설명
- 기존 LCD방식
- 신규 QR방식
- 따릉이 타입에 따라 두가지 대여소가 있다.
- 신규 QR방식 따릉이는 모든 대여소에서 대여와 반납이 가능하다.
- 기존 LCD방식 따릉이는 신규 QR방식 따릉이 대여소에 반납이 불가능하여 기존 대여소에서만 사용가능하다.
- 기존 LCD방식 따릉이는 대여번호 입력 -> 단말기 우측 잠금장치 분리
- 신규 QR방식 따릉이는 QR코드 스캔 -> 잠금 해제
- 2022년까지 'QR형 뉴따릉이'로 100% 교체될 예정이라고 한다.
7-2. 자치구별 LCD, QR 따릉이 수 비교 (groupby)
bike_06_type = bike_06.groupby(['자치구'])[['LCD', 'QR']].sum()
bike_06_type_top10 = bike_06_type.sort_values(by='LCD', ascending=False).head(n=10)
bike_06_type_top10
- groupby를 사용하여 자치구별 LCD, QR의 따릉이 수를 나타내면 위와 같다.
7-3. 각 자치구별 운영방식에 따른 따릉이 수
bike_06_type_top10.plot.bar(grid = True, figsize = (10, 8), fontsize = 15, color = ['#1BCF1C', '#FEC32D'])
plt.xticks(rotation = 0)
plt.title('<각 자치구별 운영방식에 따른 따릉이 수>', fontsize = 20)
plt.xlabel('자치구', fontsize = 15)
plt.ylabel('Count', fontsize = 15)
plt.annotate('기존 LCD 방식 최댓값', xy = (0.7,1252), xytext = (0.7,1252),
fontsize = 14, ha = 'center', color ='red',
bbox=dict(boxstyle='square', color='yellow')) # 상자안에 글자
plt.annotate('신규 QR 방식 최댓값', xy = (5,1196), xytext = (5,1196),
fontsize = 14, ha = 'center', color ='red',
bbox=dict(boxstyle='square', color='yellow'), # 상자안에 글자
arrowprops = dict(facecolor='black', width = 1, headwidth=10))
# (문자, xy = 화살표 방향, xytext = 문자, 화살표 위치, arrowprops = 화살표 성격)
- 강서구가 신형 QR방식의 따릉이를 많이 보유하고 있고
- 그 다음으로 따릉이 수, 대여장소 수를 가장 많이 보유하고 있는 송파구가 그 뒤를 잇고 있다.
- 물론 기존 LCD방식의 따릉이는 송파구가 가장 많이 보유하고 있다.
8. 따릉이 보관소(대여소)명 분석
bike_06['보관소(대여소)명'].value_counts()
- bike_06 데이터프레임에서 보관소(대여소)명 빈도를 살펴보기엔 종류가 너무 많아 따로 태깅작업을 하였다.
8-1. 태깅작업
bike_06_copy = bike_06.copy() # 데이터프레임 복사
bike_06_copy['보관소'] = 0
for i in range(len(bike_06_copy['보관소(대여소)명'])):
if '정류' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '정류장'
elif ('역' in bike_06_copy['보관소(대여소)명'].iloc[i]) or ('출구' in bike_06_copy['보관소(대여소)명'].iloc[i]):
bike_06_copy['보관소'].iloc[i]= '지하철역'
elif '초등학교' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '초등학교'
elif '중학교' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '중학교'
elif '고등학교' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '고등학교'
elif '대학교' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '대학교'
elif ('아파트' in bike_06_copy['보관소(대여소)명'].iloc[i]) or ('단지' in bike_06_copy['보관소(대여소)명'].iloc[i]) or ('편한세상' in bike_06_copy['보관소(대여소)명'].iloc[i]):
bike_06_copy['보관소'].iloc[i]= '아파트앞'
elif '공원' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '공원'
elif '주민센터' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '주민센터'
elif ('은행' in bike_06_copy['보관소(대여소)명'].iloc[i]) or ('금융' in bike_06_copy['보관소(대여소)명'].iloc[i]) or ('농협' in bike_06_copy['보관소(대여소)명'].iloc[i]):
bike_06_copy['보관소'].iloc[i]= '은행'
elif '병원' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '병원'
elif ('타워' in bike_06_copy['보관소(대여소)명'].iloc[i]) or ('빌딩' in bike_06_copy['보관소(대여소)명'].iloc[i]):
bike_06_copy['보관소'].iloc[i]= '빌딩/타워'
elif ('박물관' in bike_06_copy['보관소(대여소)명'].iloc[i]) or ('전시관' in bike_06_copy['보관소(대여소)명'].iloc[i]):
bike_06_copy['보관소'].iloc[i]= '박물관/전시관'
elif '구청' in bike_06_copy['보관소(대여소)명'].iloc[i]:
bike_06_copy['보관소'].iloc[i]= '구청'
else:
bike_06_copy['보관소'].iloc[i]= '기타'
bike_06_copy.to_csv('bike_06_copy.csv', index = False, encoding='cp949')
- '보관소' 컬럼 추가하여 태깅작업을 하였다.
- 위에 코드로 하기에는 정리가 부족하여 csv 파일 다운받아서 수기로 정리하였다.
- 예를 들어, 보관소(대여소)명 컬럼에 '역'으로 되어있는 데이터는 지하철역으로 변경하라는 코드에 '역촌점', '역촌', '역촌역' 등 지역이름에 '역'이 들어간 경우가 있었다.
bike_06_copy_1 = pd.read_csv('data/bike_06_copy_1.csv', encoding='cp949')
bike_06_copy_1
8-2. 보관소 컬럼 데이터 빈도 확인
bike_06_copy_1['보관소'].value_counts()
bike_06_copy_1[bike_06_copy_1['보관소'] == '기타'][['보관소(대여소)명']]
- 기타에는 위와 같이 oo사거리, 기업빌딩 앞 등 너무 다양해서 분류하지 큰 덩어리만 분류하였다.
8-3. 따릉이 대여소가 가장 많았던 Top1 송파구의 대여소는 어디가 가장 많을까?
bike_06_copy_1_songpa = bike_06_copy_1[bike_06_copy_1['자치구']=='송파구']['보관소'].value_counts()
bike_06_copy_1_songpa
colors = sns.color_palette('hls',len(bike_06_copy_1_songpa.index))
x = bike_06_copy_1_songpa.plot.bar(grid = True, figsize = (15,8), fontsize = 15, color = colors)
plt.xticks(rotation = 20)
plt.title('<송파구 따릉이 대여소 위치>', fontsize = 20)
plt.xlabel('대여소', fontsize = 15)
plt.ylabel('Count', fontsize = 15)
for p in x.patches:
left, bottom, width, height = p.get_bbox().bounds
plt.annotate(f'{int(height)}', (left+width/2, height+1), ha = 'center', size = 14, color = 'black')
plt.show()
- 송파구는 기타를 제외하면 지하철역과 아파트앞이 비슷한 수치로 가장 많다.
8-4. 따릉이 대여소가 가장 많았던 Top2 강서구의 대여소는 어디가 가장 많을까?
bike_06_copy_gangseo = bike_06_copy_1[bike_06_copy_1['자치구'] == '강서구']['보관소'].value_counts().head(n=10)
bike_06_copy_gangseo
colors = sns.color_palette('hls',len(bike_06_copy_gangseo.index))
x = bike_06_copy_gangseo.plot.bar(grid = True, figsize = (10, 8), fontsize = 15, color = colors)
plt.xticks(rotation = 20)
plt.title('<강서구 따릉이 대여소 위치>', fontsize = 20)
plt.xlabel('대여소', fontsize = 15)
plt.ylabel('Count', fontsize = 15)
for p in x.patches:
left, bottom, width, height = p.get_bbox().bounds
plt.annotate(f'{int(height)}', (left+width/2, height+1), ha = 'center', size = 14, color = 'black')
plt.show()
- 강서구는 기타를 제외하면 과 아파트앞과 지하철역이 비슷한 수치로 가장 많지만 송파구와 비교했을 때 지하철역보다 아파트앞에 대여소가 2개 더 많다.
8-5. 따릉이 대여소가 가장 많았던 Top3 강남구의 대여소는 어디가 가장 많을까?
bike_06_copy_gangnam = bike_06_copy_1[bike_06_copy_1['자치구'] == '강남구']['보관소'].value_counts()
bike_06_copy_gangnam
colors = sns.color_palette('hls', len(bike_06_copy_gangseo.index))
x = bike_06_copy_gangnam.plot.bar(grid = True, figsize = (12, 8), fontsize = 15, color = colors)
plt.xticks(rotation = 20)
plt.title('<강남구 따릉이 대여소 위치>', fontsize = 20)
plt.xlabel('대여소', fontsize = 15)
plt.ylabel('Count', fontsize = 15)
for p in x.patches:
left, bottom, width, height = p.get_bbox().bounds
plt.annotate(f'{int(height)}', (left+width/2, height+1), ha = 'center', size = 14, color = 'black')
plt.show()
- 강남구는 지하철역에 가장 많은 대여소가 있으며 top1, top2와 다르게 아파트앞의 대여소 개수는 지하철역의 대여소 개수의 1/3정도 밖에 되지 않는다.
9. 서울특별시 자치구별 인구 수 비교
https://data.seoul.go.kr/dataList/419/S/2/datasetView.do
seoul_population = pd.read_excel('/content/서울특별시_자치구별_인구수_2021.2분기.xlsx',
names = ['SIG_KOR_NM', 'POPULATION'])
seoul_population = seoul_population.sort_values(by = 'POPULATION', ascending = False)
seoul_population.head(n=10)
- 공공데이터 포털에서 서울특별시 자치구별 인구수 데이터를 다운받아 자치구와 인구수 컬럼만 따로 떼어냈다.
9-1. 지도에 표현하기
9-1-1. geopandas 설치 및 데이터 가져오기
pip install geopandas
import geopandas as gpd
file_path = 'https://raw.githubusercontent.com/southkorea/seoul-maps/master/juso/2015/json/seoul_municipalities_geo_simple.json'
seoul=gpd.read_file(file_path)
seoul.head()
- 위에 seoul 데이터는 서울특별시 자치구별 경도와 위도가 있는 데이터이다.
9-1-2. 데이터 merge
seoul_population_merge = pd.merge(left=seoul, right = seoul_population, on='SIG_KOR_NM')
seoul_population_merge.head(n=10)
- 자치구별 인구수 데이터(seoul_population)와 위도와 경도가 있는 데이터(seoul)를 merge하여 seoul_population_merge 데이터프레임에 저장한다.
9-1-3. 지도 시각화
final_pic=seoul_population_merge.plot(figsize=(18,15),linewidth=0.25, edgecolor='black', column='POPULATION',cmap='YlGn')
enter = '\n' # F-string 문법에서는 \를 사용할 수 없기때문에 변수에 \n을 저장한 후 사용
for index,row in seoul_population_merge.iterrows():
xy=row['geometry'].centroid.coords[:]
xytext=row['geometry'].centroid.coords[:]
if (index == 19) or (index == 15) or (index == 10):
plt.annotate(f"{row['SIG_KOR_NM']}{enter}{row['POPULATION']}",xy=xy[0], xytext=xytext[0], horizontalalignment='center',verticalalignment='center',color='yellow', size=13)
else:
plt.annotate(f"{row['SIG_KOR_NM']}{enter}{row['POPULATION']}",xy=xy[0], xytext=xytext[0], horizontalalignment='center',verticalalignment='center',color='black', size=13)
plt.axis('off')
plt.show()
- 인구수를 확인해보니 대여소가 많은 지역인 송파구와 강서구가 인구도 가장 많은 것을 알 수 있다...!