EDA - 01. Analysis Seoul CCTV (w. Pandas, matplotlib)

솔비·2023년 12월 21일
0
post-thumbnail
post-custom-banner

mini project

인구수와 CCTV 수의 상관관계를 알아보자.


🌟 개요 : 서울시 CCTV 분석
🌟 목표 : 구별 인구수와 CCTV 수의 상관관계를 알아보고, 그래프로 시각화하기

  • 데이터
    서울시 구별 인구수 : excel 파일
    서울 시 구별 CCTV 수 : csv파일
  • 출처
    서울시 열린 데이터 광장

프로젝트 시작 전 한글 및 마이너스 부호 깨짐현상 세팅

#한글폰트 깨짐 해결
from matplotlib import font_manager as fm
from matplotlib import pyplot as plt

font_path = "C:\Windows\Fonts\Arial.ttf"
font= fm.FontProperties(fname=font_path).get_name()
plt.rc('font', family = font)

#마이너스부호 깨짐 해결
import matplotlib as mpl
mpl.rcParams['axes.unicode_minus'] = False



CCTV 데이터 가공


  • CCTV_Seoul = pd.read_csv("../data/01. Seoul_CCTV.csv")
    CCTV CSV 파일 가져오기
    ➕ 한글 깨질경우 , encoding = "utf-8"



  • CCTV_Seoul.columns
    column 명 확인
    ⬇️결과
Index(['기관명', '소계', '2013년도 이전', '2014년', '2015년', '2016년'], dtype='object')



  • CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0]:"구별"},inplace = True)
    기관명 컬럼 이름 구별로 변경
    (바꾸고자 하는 컬럼의 idx 번호 활용하여 변경 컬럼명X)
    (inplace = True일 경우 원본데이터 변경)



  • CCTV_Seoul["최근증가율"] = ( (CCTV_Seoul["2016년"]+CCTV_Seoul["2015년"]+CCTV_Seoul["2016년"]) / CCTV_Seoul["2013년도 이전"] * 100)
    최근증가율 컬럼 추가



  • CCTV_Seoul.sort_values(by="최근증가율",ascending = False)
    증가율 기준 내림차순




🧷 결과



인구 수 데이터 가공


  • pop_Seoul = pd.read_excel("../data/01. Seoul_Population.xls")
    인구 수 excel 파일 가져오기
    ❗ head()로 조회 시 셀병합으로 인한 불필요한 행 발견,
    사용하지 않을 열 확인



  • pop_Seoul = pd.read_excel("../data/01. Seoul_Population.xls", header=2,usecols="B,D,G,J,N")
    read_excel에 인자추가
    : header=2 : 2행부터 / usecols="B,D,G,J,N" : 필요열만 가져오기



  • pop_Seoul.rename( columns = { pop_Seoul.columns[0] : "구별", pop_Seoul.columns[1] : "인구수", pop_Seoul.columns[2] : "한국인", pop_Seoul.columns[3] : "외국인", pop_Seoul.columns[4] : "65세이상고령자" }, inplace = True ) pop_Seoul.head()
    컬럼명 수정



  • pop_seoul.index
    cctv index 25 pop seoul index 26 확인



  • pop_Seoul.drop([0],axis=0, inplace = True)
    pop_seoul의 합계 행 삭제



  • pop_Seoul["외국인비율"] = pop_Seoul["외국인"] / pop_Seoul["인구수"] * 100
  • pop_Seoul["고령자비율"] = pop_Seoul["65세이상고령자"] / pop_Seoul["인구수"] * 100
    외국인비율, 고령자비율 컬럼 추가

🧷 결과



CCTV + 인구 수 병합


  • data_result = pd.merge(CCTV_Seoul,pop_Seoul,on="구별")
    pandas merge로 데이터 합치기
    how=inner (생략가능)



  • del data_result["2013년도 이전"]

  • del data_result["2014년"]

  • data_result.drop(["2015년","2016년"],axis =1 ,inplace = True)
    필요없는 컬럼 삭제
    drop의 경우 axis = 1은 열, =2는 행


  • data_result.set_index("구별",inplace=True)
    인덱스 "구별"컬럼으로 지정



  • data_result["CCTV비율"] = data_result["소계"] / data_result["인구수"] * 100
    인구당 CCTV 비율 확인

🧷 결과



데이터 시각화


가장 CCTV가 많은 구 시각화

지역별(idx) cctv수(소계)

def drawgraph():
    data_result["소계"].sort_values().plot(
        kind="barh", grid=True, figsize=(10,10), title = "가장 CCTV가 많은 구"
    );
drawgraph()



인구 수 대비 CCTV가 많은 구

지역별(idx) cctv비율

def drawgraph():
    data_result["CCTV비율"].sort_values().plot(
        kind="barh", grid=True, figsize=(10,10), title = "인구 수 대비 CCTV가 많은 구"
    );
drawgraph()



데이터 경향파악


❗참고

1. 인구 수 대비 CCTV의 수를 scatter로 나타내고, 경향을 파악해보자.

def drawgraph():
    plt.figure(figsize=(14,10))
    plt.scatter(data_result["인구수"],data_result["소계"],s=50)
    plt.grid(True)
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.show()
drawgraph()

인구 수 대비 CCTV 수 scatter



  • fpl = np.polyfit(data_result["인구수"],data_result["소계"],1)
    f1 = np.poly1d(fpl)
    `fx = np.linspace(100000,700000,100) : a부터 b까지 c개의 동간격 데이터 생성
def drawgraph():
    plt.figure(figsize=(14,10))
    plt.scatter(data_result["인구수"],data_result["소계"],s=50)
    plt.plot(fx,f1(fx),ls="dashed", lw=3, color = "g")
    plt.grid(True)
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.show()
drawgraph()

경향선 추가

➕인구가 40만인구에서 서울시의 전체 경향에 맞는 적당한 CCTV수는?

  • f1(400000)
    1509.7809252413338



경향과의 오차표현


  • data_result["오차"] = data_result["소계"] - f1(data_result["인구수"])
    data_result 테이블에 오차 컬럼 추가



  • df_sort_f = data_result.sort_values(by = "오차", ascending=False) #내림차순(오차가큰데이터)
  • df_sort_t = data_result.sort_values(by = "오차", ascending=True) #오름차순(오차가적은데이터)
    오차가 많은 데이터와 적은 데이터 각각 내림차순 오름차순하여 변수에 담기



from matplotlib.colors import ListedColormap

# colormap을 사용자정의로 세팅
color_step = ("#e74c3c","#2ecc71","#95a9a6","#2ecc71","#3498db","#3498db")

my_cmap = ListedColormap(color_step)
def drawgraph():
    plt.figure(figsize=(14,10))
    plt.scatter(data_result["인구수"],data_result["소계"],s=50,c=data_result["오차"],cmap = my_cmap)
    plt.plot(fx,f1(fx),ls="dashed", lw=3, color = "g")
    plt.grid(True)
    plt.xlabel("인구수")
    plt.ylabel("CCTV")

    for i in range(5) :
        #상위
        plt.text(df_sort_f["인구수"][i]*1.02,df_sort_f["소계"][i]*0.98, df_sort_f.index[i],fontsize = 10)

        #하의
        plt.text(df_sort_t["인구수"][i]*1.02,df_sort_t["소계"][i]*0.98, df_sort_t.index[i],fontsize = 10)

    plt.colorbar()
    plt.show()
drawgraph()

scatter에 인덱스값 추가 및 컬러바 삽입


결과


전체코드




Zero Base 데이터분석 스쿨
Daily Study Note
profile
Study Log
post-custom-banner

0개의 댓글