In [1]:
import pandas as pd
In [2]:
# 서울 열린광장 데이터 cctv
CCTV_Seoul = pd.read_csv('../../data/01. CCTV_in_Seoul.csv', encoding='utf-8')
CCTV_Seoul.head()
Out[2]:
In [3]:
CCTV_Seoul.columns[0]
Out[3]:
pandas dataframe의 칼럼 이름 변경¶
- df.rename(columns = {'기존 칼럼' : '바꿀 칼럼',}, inplace =True)
- df.columns = ['바꿀 칼럼1', '바꿀 칼럼2']
In [4]:
CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0]: '구별'}, inplace=True)
CCTV_Seoul.head()
Out[4]:
엑셀 파일 읽기 - 서울시 인구 현황¶
In [5]:
pop_Seoul = pd.read_excel('../../data/01. population_in_Seoul.xls ',
header = 2,
usecols = 'B, D, G, J, N') # parse_cols
pop_Seoul.head()
Out[5]:
In [6]:
pop_Seoul.rename(columns={pop_Seoul.columns[0] : '구별',
pop_Seoul.columns[1] : '인구수',
pop_Seoul.columns[2] : '한국인',
pop_Seoul.columns[3] : '외국인',
pop_Seoul.columns[4] : '고령자'}, inplace = True)
pop_Seoul.head()
Out[6]:
데이터 파악하기¶
- 데이터 정제
In [7]:
CCTV_Seoul.sort_values(by='소계', ascending=False).head(5)
Out[7]:
In [8]:
# 최근 3년간 증가율 = (2016+2015+2014) / 2013년도 이전 * 100
CCTV_Seoul['최근증가율'] = (CCTV_Seoul['2016년'] + CCTV_Seoul['2015년'] + \
CCTV_Seoul['2014년']) / CCTV_Seoul['2013년도 이전'] * 100
CCTV_Seoul.sort_values(by='최근증가율', ascending=False).head(5)
Out[8]:
4. 서울시 인구 데이터 파악하기¶
In [9]:
pop_Seoul.head()
Out[9]:
In [10]:
pop_Seoul.drop([0], inplace = True) # 합계 행 삭제
pop_Seoul.head()
Out[10]:
In [11]:
# 구 이름이 아닌 nan이 보임
pop_Seoul['구별'].unique()
Out[11]:
In [12]:
# isnull 명령어로 누락값 데이터 추출
pop_Seoul[pop_Seoul['구별'].isnull()]
Out[12]:
In [13]:
pop_Seoul.tail()
Out[13]:
In [14]:
pop_Seoul.drop([26], inplace=True)
pop_Seoul.tail()
Out[14]:
In [15]:
pop_Seoul['외국인비율'] = pop_Seoul['외국인'] / pop_Seoul['인구수'] * 100
pop_Seoul['고령자비율'] = pop_Seoul['고령자'] / pop_Seoul['인구수'] * 100
pop_Seoul.head()
Out[15]:
In [16]:
# 인구수가 많은 순으로 정렬
pop_Seoul.sort_values(by='인구수', ascending=False).head(5)
Out[16]:
In [17]:
pop_Seoul.sort_values(by='외국인', ascending=False).head(5)
Out[17]:
In [18]:
pop_Seoul.sort_values(by='외국인비율', ascending=False).head(5)
Out[18]:
In [19]:
pop_Seoul.sort_values(by='고령자', ascending=False).head(5)
Out[19]:
5. CCTV 데이터와 인구 데이터 합치고 분석¶
In [20]:
data_result = pd.merge(CCTV_Seoul, pop_Seoul, on = '구별')
data_result.head()
Out[20]:
In [21]:
# drop - 행 방향 삭제, del - 열 삭제
del data_result['2013년도 이전']
del data_result['2014년']
del data_result['2015년']
del data_result['2016년']
data_result.head()
Out[21]:
In [22]:
data_result.set_index('구별', inplace=True)
data_result.head()
Out[22]:
In [23]:
# CCTV 개수와 고령자 비율은 약한 음의 상관관계
import numpy as np
np.corrcoef(data_result['고령자비율'], data_result['소계'])
Out[23]:
In [24]:
# CCTV 개수와 외국인 비율과는 큰 의미가 없음
np.corrcoef(data_result['외국인비율'], data_result['소계'])
Out[24]:
In [25]:
data_result.sort_values(by='인구수', ascending=False).head()
Out[25]:
6. CCTV와 인구 현황 그래프로 분석¶
In [26]:
import matplotlib.pyplot as plt
import platform
from matplotlib import font_manager, rc
plt.rcParams['axes.unicode_minus'] = False # - 기호 깨지는 것 방지
# f_path = "/Library/Fonts/AppleGothic.ttf" -> MAC
f_path = "C:/Windows/Fonts/malgun.ttf"
font_name = font_manager.FontProperties(fname=f_path).get_name()
rc('font', family=font_name)
In [27]:
data_result.head()
Out[27]:
In [28]:
plt.figure()
data_result['소계'].plot(kind='barh', grid=True, figsize=(10,10))
plt.show()
In [29]:
# CCTV 갯수가 많은 순으로 정렬하여 plot
data_result['소계'].sort_values().plot(kind='barh',
grid=True, figsize=(10,10))
Out[29]:
In [30]:
# 인구 대비 CCTV 비율이 높은 순으로 정렬 후 plot
data_result['CCTV_비율'] = data_result['소계'] / data_result['인구수'] * 100
data_result['CCTV_비율'].sort_values().plot(kind='barh',
grid=True, figsize=(10,10))
Out[30]:
In [31]:
import seaborn as sns
colors = list('rgby')
data_result['CCTV_비율'].sort_values().plot(kind='barh',
grid=True, figsize=(10,10),
color = colors)
plt.show()
In [32]:
# sns.color_palette("atrribue") -> seaborn.pydata.org
colors = sns.color_palette("viridis", len(data_result.index))
data_result['CCTV_비율'].sort_values().plot(kind='barh',
grid=True, figsize=(10,10),
color = colors)
plt.show()
In [33]:
plt.figure(figsize=(6,6))
plt.scatter(data_result['인구수'], data_result['소계'],
s=70, color = colors)
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()
polyfit 함수¶
- y = ax + b (a: 기울기, b: 절편)
In [34]:
# 기울기, 절편, 1차원
fp1 = np.polyfit(data_result['인구수'], data_result['소계'], 1)
fp1
Out[34]:
In [35]:
f1 = np.poly1d(fp1) # 매개변수로부터 모델 생성
fx = np.linspace(100000, 700000, 100) # 시작, 끝(포함), 갯수
attribute¶
- ls : linestyle
- lw : 선 굵기
- s : 점(scatter) size
In [36]:
plt.figure(figsize=(10, 10))
plt.scatter(data_result['인구수'], data_result['소계'],
s=70, color = colors)
plt.plot(fx, f1(fx), ls = 'dotted', lw=3, color='r')
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()
7. 설득력 있는 자료 만들기¶
In [37]:
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()
Out[37]:
In [38]:
plt.figure(figsize=(10, 10))
plt.scatter(data_result['인구수'], data_result['소계'],
c=data_result['오차'], s=70)
plt.plot(fx, f1(fx), ls = 'dotted', lw=3, color='r')
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('CCTV')
plt.colorbar()
plt.grid()
plt.show()
In [ ]:
반응형
'데이터분석' 카테고리의 다른 글
[23.06.30] 웹 크롤링 - 21(1) (0) | 2023.06.30 |
---|---|
[23.06.29] 데이터 시각화 - 20(1) (0) | 2023.06.29 |
[23.06.28] 데이터 시각화(폰트 깨짐 방지, warning 무시) - 19(1) (0) | 2023.06.28 |
[23.06.27] SQL - 18(1) (0) | 2023.06.27 |
[23.06.26] SQL - 17(1) (0) | 2023.06.26 |