본문 바로가기
수업(국비지원)/Python

[Python] CCTV_in_Seoul.csv파일과 population_in_Seoul.xls파일을 분석하기

by byeolsub 2023. 4. 26.

 📌 파일읽기

##################################
# CCTV_in_Seoul.csv파일과 population_in_Seoul.xls파일을 분석하기
'''
서울시 각 구별 CCTV수를 파악하고, 인구대비 CCTV 비율을 파악해서 순위 비교
서울시 각 구별 CCTV수 : 01. CCTV_in_Seoul.csv
서울시 인구 현황      : 01. population_in_Seoul.xls
'''

import pandas as pd
CCTV_Seoul = pd.read_csv("data/01. CCTV_in_Seoul.csv")
CCTV_Seoul.info()

Pop_Seoul = pd.read_excel("data/01. population_in_Seoul.xls")
Pop_Seoul.info()
Pop_Seoul.head()

- 데이터 전처리(필요한 데이터만 조회)

'''
 header 정보 : 3번째 행
 셀 데이터 : B,D,G,J,N
'''
Pop_Seoul = pd.read_excel("data/01. population_in_Seoul.xls",\\
                          header=2, usecols="B,D,G,J,N")
Pop_Seoul.info()
Pop_Seoul.head()

# 컬럼명 변경하기
CCTV_Seoul.columns
# CCTV_Seoul : 기관명 => 구별
CCTV_Seoul.rename(columns={"기관명":"구별"},inplace=True)
CCTV_Seoul.info()

Pop_Seoul.columns
# Pop_Seoul : [구별, 인구수, 한국인, 외국인, 고령자]
Pop_Seoul.columns = ["구별","인구수","한국인","외국인","고령자"]
Pop_Seoul.info()

# 인구데이터의 첫번째 행을 제거하기(합계행 제거)
Pop_Seoul.drop([0],axis=0, inplace=True)
Pop_Seoul.head()


 📌 데이터 분석

'''
  CCTV 최근증가율이 높은 구 5개를 조회하기
  1. 최근증가율 컬럼 추가
     (2014~2016까지의 최근 3년간 CCTV수의 합)/(2013년도 CCTV수) * 100
  2. 최근증가율 컬럼으로 내림차순 정렬하여 상위5개만 조회.   
'''
#1. 최근증가율 컬럼추가
CCTV_Seoul["최근증가율"] = ((CCTV_Seoul["2014년"] + CCTV_Seoul["2015년"] \\
		+ CCTV_Seoul["2016년"]) /CCTV_Seoul["2013년도 이전"] * 100)
CCTV_Seoul.info()

#2. 최근증가율 컬럼으로 내림차순 정렬하여 상위 5개만 조회.
CCTV_Seoul_rate = CCTV_Seoul.sort_values(by='최근증가율',ascending=False)[:5]
CCTV_Seoul_rate


 📌 데이터 분석

'''  
외국인비율,고령자비율이 높은 구 5개 조회하기  
 1. Pop_Seoul 데이터의 외국인비율,고령자비율 컬럼 추가하기    
    외국인비율 : 외국인/인구수 * 100    
    고령자비율 : 고령자/인구수 * 100  
 2. 외국인비율,고령자비율로 내리차순 정렬하여 상위5개 조회하기  
'''
#  1. Pop_Seoul 데이터의 외국인비율,고령자비율 컬럼 추가하기
#    외국인비율 : 외국인/인구수 * 100
#    고령자비율 : 고령자/인구수 * 100

Pop_Seoul["외국인 비율"] = (Pop_Seoul["외국인"]/Pop_Seoul["인구수"] * 100)
Pop_Seoul["고령자 비율"] = (Pop_Seoul["고령자"]/Pop_Seoul["인구수"] * 100)
Pop_Seoul.info()

#  2. 외국인비율,고령자비율로 내리차순 정렬하여 상위5개 조회하기
Pop_Seoul.sort_values(by="외국인 비율",ascending=False)[:5]
Pop_Seoul.sort_values(by="고령자 비율",ascending=False)[:5]

#구별컬럼을 연결컬럼으로 하여 CCTV_Seoul, Pop_Seoul  데이터 합하기
data_result = pd.merge(CCTV_Seoul,Pop_Seoul)
data_result.info()

#data_result : 2013년도 이전, 2014년,2015년,2016년 컬럼제거
#del
del data_result["2013년도 이전"], data_result["2014년"],\\
    data_result["2015년"], data_result["2016년"]
data_result.info()

#구별 컬럼을 인덱스로 변경하기 : set_index
data_result = data_result.set_index("구별")

#인구수와 소계 컬럼과의 상관계수 구하기
data_result[["인구수","소계"]].corr()

#산점도 그래프 출력하기
import seaborn as sns
sns.pairplot(data_result[["인구수","소계"]])

#회귀 그래프 출력하기
sns.regplot(x="인구수", y="소계", data=data_result)


 📌

'''
CCTV비율 컬럼추가하기
CCTV비율 : 인구수대비 CCTV개수 CCTV개수/인구수 * 100
'''
data_result["CCTV비율"] = (data_result["소계"] / data_result["인구수"] * 100)
data_result.info()
data_result["CCTV비율"]

# 수평막대그래프로 작성하기
data_result["CCTV비율"].sort_values()\\
    .plot(kind="barh", grid=True, figsize=(10,10))

# matplot을 이용하여 산점도와 회귀선 그래프 작성하기
import numpy as np
# polyfit : 수학적 함수. 방정식 상수값 리턴
#           모든 점과의 차이가 가장 적은 직선의 상수값을 리턴
'''
 np.polyfit(x값, y값,차수) 
    : x, y 모든 점과의 차이가 가장 적은 선의 값을 리턴
  
  차수 : 1차함수 : 직선 : ax + b, (a: 기울기, b: 절편)
         2차함수 : 곡선 : ax**2 + bx + c
'''  
plt.rc("font", family="AppleGothic") #맥글씨

fp1 = np.polyfit\\
        (data_result['인구수'], data_result['소계'], 1) # 기울기, y절편의 상수 리턴
fp1 
# y = f1(fx) : 기대 CCTV 개수  
f1 = np.poly1d(fp1) # 함수. fp1상수값에 맞는 함수.

# x축의 값. 10만~70만의 값을 100개로 균등분할
fx = np.linspace(100000, 700000, 100)        
plt.figure(figsize=(6,6))

# 산점도
plt.scatter(data_result['인구수'], data_result['소계'], s=50) 

# 회귀선
# fx : x 축의 값
# f1(fx) : x축의 값의 대비 결과값. y축의 값
# ls='dashed' :선의 종류. 댓쉬선
# lw=3 : 선의 두께
# color='g' : green 색상
plt.plot(fx,f1(fx), ls='dashed', lw=3, color='g') # 직선

plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()

# 기대CCTV 개수 = f1(인구수)
# 오차 컬럼 생성 : |실제 cctv개수 - 기대 cctv개수| 절대값처리
# np.abs : 절대값
# data_result["소계"] : 실제 cctv 개수
# f1(data_result["인구수"]) : 기대 cctv 개수
data_result["오차"] =\\
    np.abs(data_result["소계"] - f1(data_result["인구수"]))
data_result["오차"].head()

df_sort = data_result.sort_values(by="오차",ascending=False) 
df_sort.head()

plt.figure(figsize=(8,8)) # 그래프 크기 지정

# 산점도 그래프
#c는 컬러를 뜻함 오차로 바꾸어표시
plt.scatter(data_result['인구수'], data_result['소계'],
            c=data_result['오차'],s=50)

# 회귀선 그래프
plt.plot(fx,f1(fx), ls='dashed', lw=3, color='g') 
# plt.text(x좌표,y좌표,출력문자열,글자크기) : 문자출력
# df_sort['인구수][n]*1.02 : x축의 좌표.
# df_sort['소계'][n]*0.98 : y축의 좌표.
# df_sort.index[n] : 출력문자열
for n in range(10) : # 10개의 구 정보만 출력.
    plt.text(df_sort['인구수'][n]*1.02, df_sort['소계'][n]*0.98,
             df_sort.index[n], fontsize=10)
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.colorbar() 
plt.grid()
plt.show()