티스토리 뷰
출처 : 파이썬으로 데이터 주무르기 by 민형기
1단원 서울시 구별 CCTV현황 분석¶
- CCTV 현황과 인구 현황 데이터 구하기
- 파이썬에서 텍스트 파일과 엑셀 파일을 읽기 -pandas
- pandas 기초 익히기
- pandas를 이용해서 CCTV와 인구 현황 데이터 파악하기
- pandas 고급기능 - 두 DataFrame 병합하기
- CCTV 데이터와 인구 현황 데이터를 합치고 분석하기
- 파이썬의 대표 시각화 도구 - Matplotlib
- CCTV 현황 그래프로 분석하기
지난시간 정리
1. ~ 3.(https://jfun.tistory.com/210)
4. ~ 5.(https://jfun.tistory.com/211)
오늘은 1단원을 마쳐보도록 하겠다.¶
1-6 CCTV 데이터와 인구 현황 데이터를 합치고 분석하기¶
# merge를 사용하여 병합시켜 보자.
data_result = pd.merge(CCTV_Seoul, pop_Seoul, on='구별')
data_result.head()
# 의미 없는 컬럼을 del 명령어를 이용하여 지우도록 하자.
# 일반적으로 행을 삭제할때는 drop을 열을 삭제할때는 del을 사용한다.
del data_result['2013년도 이전']
del data_result['2014년']
del data_result['2015년']
del data_result['2016년']
data_result.head()
# 그래프 그릴 것을 고려하여 index를 구로 고치자.
data_result.set_index('구별', inplace=True)
data_result.head()
다양한 접근은 개인적으로 해보고, 고령자비율, 외국인비율, 인구수 중에서 무슨 데이터와 CCTV를 비교할지 정해보겠다. 그렇게 하는 가장 단순한 작업이 상관계수를 조사하는 것이다. 상관계수의 절대값이 클수록 두 데이터는 관계가 있다고 볼 수 있다.
먼저 numpy의 corrcoef명령어 를 사용하여 상관계수를 구해보고 상관계수가 가장 큰 값인 데이터를 비교하겠다.
np.corrcoef(data_result['고령자비율'], data_result['소계'])
CCTV 개수와 고령자 비율은 약한 음의 상관관계임을 알 수 있다.
np.corrcoef(data_result['외국인비율'], data_result['소계'])
외국인의 비율과는 큰 의미가 없다고 할 수 있다.
np.corrcoef(data_result['인구수'], data_result['소계'])
인구수와는 약한 상관관계가 있다고 볼 수 있다.
이김에 CCTV와 인구수의 관계를 좀 더 들여다보자.
data_result.sort_values(by='소계', ascending=False).head()
data_result.sort_values(by='인구수', ascending=False).head()
CCTV가 많이 설치된 구와 인구수가 많은 구를 시각적으로 비교해보자.
1-7 파이썬의 대표 시각화 도구 - Matplotlib¶
import matplotlib.pyplot as plt
%matplotlib inline
# 그래프의 결과를 출력세션에 나타나게 한다.
plot¶
plt.figure
plt.plot([1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1,0])
plt.show()
import numpy as np
# 0부터 12까지 0.01 간격으로 데이터를 만든다.
# 값을 하나만 가진 변수가 아니다. 약 1200개 정도의 값을 가진 일종의 배열이다.
t = np.arange(0, 12, 0.01)
y = np.sin(t)
plt.figure(figsize=(10,6)) # 그림 크기
plt.plot(t,y) # t와 y에 관계의 그래프
plt.show()
plt.figure(figsize=(10,6))
plt.plot(t,y)
plt.grid()
plt.xlabel('time')
plt.ylabel('Amplitude')
plt.title('Example of sinewave')
plt.show()
# 명령을 두 개 넣어서 한 화면에 그래프를 두 개 만들자
# 범례(legend)를 추가해보자.
plt.figure(figsize=(10,6))
plt.plot(t, np.sin(t), label='sin')
plt.plot(t, np.cos(t), label='cos')
plt.grid()
plt.legend()
plt.xlabel('time')
plt.ylabel('Amplitude')
plt.title('Example of sinewave')
plt.show()
# lw로 선의 굵기를 조정할 수 있으며, color 옵션으로 색상을 지정할 수 있다.
plt.figure(figsize=(10,6))
plt.plot(t, np.sin(t), lw=3, label='sin')
plt.plot(t, np.cos(t), 'r', label='cos')
plt.grid()
plt.legend()
plt.xlabel('time')
plt.ylabel('Amplitude')
plt.title('Example of sinewave')
plt.show()
t=[0, 1, 2, 3, 4, 5, 6]
y=[1, 4, 5, 8, 9, 5, 3]
plt.figure(figsize=(10,6))
plt.plot(t, y, color='green')
plt.show()
# linestyle을 이용하여 선 스타일을 지정할 수 있다.
plt.figure(figsize=(10,6))
plt.plot(t, y, color='green', linestyle='dashed')
plt.show()
# marker 옵션으로 데이터가 존재하는 곳에 마킹할 수 있다.
plt.figure(figsize=(10,6))
plt.plot(t, y, color='green', linestyle='dashed', marker='o')
plt.show()
# markerfacecolor옵션을 이용하여 색을, markersize 옵션을 이용하여 크기를 지정할 수 있다.
plt.figure(figsize=(10,6))
plt.plot(t, y, color='green', linestyle='dashed', marker='o',
markerfacecolor = 'blue', markersize=12)
plt.xlim([-0.5, 6.5])
plt.ylim([0.5, 9.5])
plt.show()
scatter¶
t=np.array([0,1,2,3,4,5,6,7,8,9])
y=np.array([9,8,7,9,8,3,2,4,3,4])
plt.figure(figsize=(10,6))
plt.scatter(t,y)
plt.show()
# marker를 지정해보자.
plt.figure(figsize=(10,6))
plt.scatter(t,y,marker='>')
plt.show()
# x축 값에 따라 색상을 바꾸는 clor map 지정
colormap = t
plt.figure(figsize=(10,6))
plt.scatter(t,y, s=50, c = colormap, marker='>')
plt.colorbar()
plt.show()
numpy 랜덤변수 함수¶
# 랜덤 변수 함수를 이용해서 데이터 3개를 만들자.
# loc : 평균값, scale : 표준편차
s1 = np.random.normal(loc=0, scale=1, size=1000)
s2 = np.random.normal(loc=5, scale=0.5, size=1000)
s3 = np.random.normal(loc=10, scale=2, size=1000)
plt.figure(figsize=(10,6))
plt.plot(s1, label='s1')
plt.plot(s2, label='s2')
plt.plot(s3, label='s3')
plt.legend()
plt.show()
# boxplot으로 표현해보자.
plt.figure(figsize=(10,6))
plt.boxplot((s1, s2, s3))
plt.grid()
plt.show()
1-8 CCTV 현황 그래프로 분석하기¶
# 한글 폰트 지원
import platform
from matplotlib import font_manager, rc
plt.rcParams['axes.unicode_minus']=False
if platform.system() == 'Darwin':
rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
path = 'c:/Windows/Fonts/malgun.ttf'
font_name = font_manager.FontProperties(fname=path).get_name()
rc('font', family=font_name)
else:
print('Unkown system... sorry~~~~')
# 결과 변수 다시 확인
data_result.head()
# pandas 데이터 뒤에 plot 명령어를 붙인다
# kind='barh' 수평bar 그래프.
data_result['소계'].plot(kind='barh', grid=True, figsize=(10,10))
plt.show()
# 위 그림은 큰 의미를 찾기 어렵다. 정렬을 통해 좀 더 보기 좋게 바꿔보자.
data_result['소계'].sort_values().plot(kind='barh', grid=True, figsize=(10,10))
plt.show()
CCTV의 개수가 강남구가 월등히 많다는 것을 알 수 있다. 뒤를 이어 양천구, 서초구, 은평구가 꽤 많은 CCTV가 설치되어 있다. 그리고 하위 그룹이 얼마나 적은 수의 CCTV를 가지고 있는지도 확인할 수 있다.
# 인구 대비 CCTV 비율을 계산해서 정렬하고 그려보자.
data_result['CCTV비율'] = data_result['소계'] / data_result['인구수'] *100
data_result['CCTV비율'].sort_values().plot(kind='barh', grid=True, figsize=(10,10))
plt.show()
인구대비 CCTV 수를 보니 이번에는 용산구와 종로구가 월등히 높다. 그런데 송파구는 인구 대비로 봐도 CCTV 비율이 낮다.
조금 더 나아가 scatter 함수를 사용하여 보자.
# 마커 s =50
plt.figure(figsize=(6,6))
plt.scatter(data_result['인구수'], data_result['소계'], s = 50)
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()
# 위 그래프를 대표하는 직선을 하나 그려보자.
#아까 CCTV와 인구수는 양의 상관관계가 있다는 것을 보였었다.
#numpy의 polyfit 명령으로 손쉽게 직선을 만들 수 있다.
fp1 = np.polyfit(data_result['인구수'], data_result['소계'], 1)
fp1
f1 = np.poly1d(fp1) # y축 데이터
fx = np.linspace(100000, 700000, 100) # x축 데이터
plt.figure(figsize=(10,10))
plt.scatter(data_result['인구수'], data_result['소계'], s=50)
plt.plot(fx, f1(fx), ls='dashed', lw=3, color='g')
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()
여기에 두 가지 방법을 넣고 싶다.
하나는 직선이 이 전체 데이터의 대표 값 역할을 한다면
- 이 경향성에서 멀이 있는 구는 이름을 나타나도록 하고 싶다는 것
- 직선에서 멀어질수록 다른 색을 내타내는 것
# 오차를 계산할 수 있는 코드를 만들고 오차가 큰 순으로 데이터를 정렬해서 다시 저장하자.
fp1 = np.polyfit(data_result['인구수'], data_result['소계'], 1)
f1 = np.poly1d(fp1)
fx = np.linspace(100000, 700000, 100)
data_result['오차'] = np.abs(data_result['소계'] - f1(data_result['인구수']))
df_sort = data_result.sort_values(by='오차', ascending=False)
df_sort.head()
# 이제 텍스트와 colormap을 입히자.
plt.figure(figsize=(14, 10))
plt.scatter(data_result['인구수'], data_result['소계'],
c=data_result['오차'], s=50)
plt.plot(fx, f1(fx), ls='dashed', lw=3, color='g')
for n in range(10):
plt.text(df_sort['인구수'][n]*1.02, df_sort['소계'][n]*0.98,
df_sort.index[n], fontsize=15)
plt.xlabel('인구수')
plt.ylabel('인구당비율')
plt.colorbar()
plt.grid()
plt.show()
직선을 기준으로 위에 있는 '강남구', '양천구', '서초구', '은평구', '용산구는 서울시 전체 지역의 일반적인 경향보다 CCTV가 많이 설치된 지역이다.
직선을 기준으로 아래 있는 '송파구', '강서구', '중랑구', '마포구', '도봉구'는 서울시 전체 지역의 일반적인 경향보다 CCTV가 적게 설치된 지역이다.
특히 강남구는 월등히 많은 CCTV가 설치되어 있지만, 송파구는 너무나도 적은 수의 CCTV를 가지고 있다.
'beginner > 파이썬 분석' 카테고리의 다른 글
서울시 범죄 현황 분석 -2 (0) | 2019.07.03 |
---|---|
서울시 범죄 현황 분석 -1 (0) | 2019.07.03 |
서울시 구별 CCTV 현황 분석-2 (0) | 2019.06.28 |
서울시 구별 CCTV 현황 분석-1 (1) | 2019.06.27 |
맥주 추천시스템-데이터분할 (0) | 2019.04.23 |