ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 인구 통계 분석 - 위키피디아 크롤링 및 데이터 분석 02
    빅데이터/Data-Analysis 2022. 3. 5. 13:19

    유투버 'todaycode오늘코드'님 강의 참조

     

     

     

     

    • 통계청 데이터 '출생아수'로 진행 예정

     

     

     

     

     

    01 데이터 준비

    *데이터 다운로드 주소
    https://kosis.kr/statHtml/statHtml.do?orgId=101&tblId=INH_1B81A01&vw_cd=MT_GTITLE01&list_id=101&seqNo=&lang_mode=ko&language=kor&obj_var_id=&itm_id=&conn_path=MT_GTITLE01

    import pandas as pd
    df_kosis = pd.read_csv('출생아수_시도_시_군_구__20220305113211.csv',encoding='cp949')
    df_kosis.head()
    
    df_kosis.shape
    (19, 865)

     

     

     

     

    02 데이터 전처리

     

    분석전에는 판다스를 쉽게 쓰기 위해 피벗테이블 형태가 아닌 컬럼형태로 만들어 줘야 한다. 시군구별, 년도월 등을 따로 만들어야 쓰기 편하다

    • 또한 데이터를 잘 들여다 보면 전체는 .월, 남자는 .01.1, 여자는 .01.2 로 되어있다. 즉 계(명), 남자(명), 여자(명)이 한번 더 열로 표현되는데 없애줘도 된다.

    • 판다스에서는 자동적으로 열을 없애고 데이터를 알아서 맞춰주는 .melt()라이브러리가 있다.

    df_kosis.melt(id_vars='시군구별')

    .melt()를 하게되면 시군구별/년월 컬럼이 없어지고 이 두개의 컬럼이 행으로 녹아든게 보인다

     

    ▶ 조금 더 깊게 데이터 들여다 보기

    df = df_kosis.melt(id_vars='시군구별')
    df.head()

    • .melt() 이후에도 0번째 컬럼에 시군구별이라고 해서 뭔가 겹치는 데이터 혹은 필요없는 컬럼들을 들고 있는 열이 보인다. 
    df['시군구별'].unique()
    array(['시군구별', '전국', '서울특별시', '부산광역시', '대구광역시', '인천광역시', '광주광역시', '대전광역시',
           '울산광역시', '세종특별자치시', '경기도', '강원도', '충청북도', '충청남도', '전라북도', '전라남도',
           '경상북도', '경상남도', '제주특별자치도'], dtype=object)
    • 시군구별만 찍어보면 전국 이름이 나오나 하나가 '시군구별' 컬럼이 있다.
    # 불리언 인덱싱을 데이터 프레임으로 보는 방법
    df[df['시군구별'] == '시군구별']

    • 즉 시군구별 컬럼에 시군구별로 되어있는것만 뽑아보면 의미가 없는 데이터라는것을 알 수 있다. 이 값 없이 데이터 프레임을 만들자
    # 필요 없는 컬럼 제거
    print(df.shape)
    df = df[df['시군구별'] != '시군구별'].copy()
    df.shape
    (16416, 3)
    (15552, 3)
    
    df['시군구별'].unique()
    array(['전국', '서울특별시', '부산광역시', '대구광역시', '인천광역시', '광주광역시', '대전광역시',
           '울산광역시', '세종특별자치시', '경기도', '강원도', '충청북도', '충청남도', '전라북도', '전라남도',
           '경상북도', '경상남도', '제주특별자치도'], dtype=object)

     

     

     

    ▶ 년도, 월, 성별, 텍스트 데이터 전처리

    • 아직 전처리가 조금 남아 있다

    1. 'variable' 컬럼 수정

    # 년도, 월, 성별, 텍스트 데이터 전처리
    df['variable']
    1          1997.01
    2          1997.01
    3          1997.01
    4          1997.01
    5          1997.01
               ...
               
    -> 먼저 전체/남녀 구분을 해줘야 한다
    # 남/녀/전체 구분
    # expand='True' 를 하면 스플릿 한 부분대로 나눠서 데이터 프레임을 만듬
    df['variable'].str.split('.', expand=True)

     

    # 남/녀/전체 구분
    # expand='True' 를 하면 스플릿 한 부분대로 나눠서 데이터 프레임을 만듬
    df['연도'] = df['variable'].str.split('.', expand=True)[0]
    df.head()

    # 남/녀/전체 구분
    # expand='True' 를 하면 스플릿 한 부분대로 나눠서 데이터 프레임을 만듬
    df['연도'] = df['variable'].str.split('.', expand=True)[0]
    df['월'] = df['variable'].str.split('.', expand=True)[1]
    
    # 0(None)=전체, 1=남자, 2=여자
    df['성별'] = df['variable'].str.split('.', expand=True)[2]
    df.head()
    
    df['성별'].unique()
    array([None, '1', '2'], dtype=object)
    -> 타입이 오브젝트인것을 주의

     

    # None값 처리
    df['성별'] = df['성별'].fillna('전체')
    
    # 번호 처리
    df['성별'] = df['성별'].replace('1', '남자').replace('2','여자')
    df['성별'].unique()
    array(['전체', '남자', '여자'], dtype=object)
    
    df['성별'].value_counts()
    전체    5184
    남자    5184
    여자    5184

     

    2. 컬럼명 수정

    # 컬럼명 rename 처리
    df = df.rename(columns={'variable':'기간','value':'출생아수'})
    df.head()

     

     

     

     

     

     

    03 분석 및 시각화

    df.info()
     #   Column  Non-Null Count  Dtype 
    ---  ------  --------------  ----- 
     0   시군구별    15552 non-null  object
     1   기간      15552 non-null  object
     2   출생아수    15552 non-null  object
     3   연도      15552 non-null  object
     4   월       15552 non-null  object
     5   성별      15552 non-null  object
    • 출생아수를 분석 및 시각화해야하는데 'object'형이다. 수치형으로 바꿔 주자
    # 출생아수 수치형 변환
    df['출생아수'].astype(int)
    ValueError: invalid literal for int() with base 10: '-'
    --> 이 오류를 처리
    
    
    df['출생아수'] = df['출생아수'].replace('-', np.nan)
    df['출생아수'].astype(int)
    ValueError: cannot convert float NaN to integer
    --> 다시 오류 처리
    
    df['출생아수'] = df['출생아수'].astype(float)
    
    df['출생아수'].describe()
    count    15012.000000
    mean      3012.725286
    std       6587.701782
    min         30.000000
    25%        621.000000
    50%       1025.000000
    75%       1908.250000
    max      63268.000000
    
    
    # 0일때 계산하면 아래와 같다
    df['출생아수'] = df['출생아수'].replace('-', 0)
    df['출생아수'].describe()
    count    15552.000000
    mean      2908.116770
    std       6495.774215
    min          0.000000
    25%        589.000000
    50%        989.000000
    75%       1833.000000
    max      63268.000000
    • 최종적으로 Nan값을 처리하는데에 있어서 int값으로 바꿀 수 없는데 '0'으로 바꿔서 처리 할 수 도 있다. 하지만 0으로 바꿔버리게 되면 출생아수가 아예 그달 혹은 그 년도에 0이되버리기 때문에 계산에 엄청난 오류가 발생하게된다. 한명도 안낳을수는 날은 없기때문에 그대로 소수점 처리로 바꿔줘야 문제가 없다

     

     

    ▶ 전체 지역 분석

    # 전체 지역 분석
    df_all = df[(df['시군구별'] == '전국') & (df['성별']=='전체')]
    df_all.head()

    # 시각화
    import matplotlib.pyplot as plt
    plt.rc('font', family = 'Malgun Gothic' )
    df_all.set_index(['연도','월']).plot(figsize=(15,4));

    전국적으로도 출생아수는 계속해서 감소하고 있고 특정 주기성으로 출생아수가 늘었다 줄었다 하는것을 볼 수 있다

    • 이렇계 계절/주기성은 plot형태로 많이 그린다.
    df_all[-24:].set_index(['연도','월']).plot.bar(figsize=(15,4));

    ▶ 'Seaborn' 시각화

    import seaborn as sns
    plt.figure(figsize=(15,4))
    sns.barplot(data=df_all, x='연도', y='출생아수')
    
    plt.figure(figsize=(15,4))
    sns.lineplot(data=df_all, x='연도', y='출생아수')

    • 판다스와 시본의 시각화 가장 큰 차이점은 판다스는 정말 데이터 값 그대로 들어가는 반면 시본은 평균값, 신뢰구간등 다 계산을 해서 보여 준다. 즉 판다스로 정확한 수치를 표현하고싶으면 계산을 따로하여 일일히 표시해야한다.
    plt.figure(figsize=(15,4))
    sns.lineplot(data=df_all, x='연도', y='출생아수', hue='월')

     

     

     

     

    ▶ 지역별 분석

    # 지역별 분석
    df_local = df[df['시군구별'] != '전국'].copy()
    
    plt.figure(figsize=(15,4))
    sns.pointplot(data=df_local, x='연도', y='출생아수', hue='성별')

    전체적으로 계속 줄고 있고 남아가 여아보다 많이 낳아졌다는것을 볼 수 있다

     

    df_local_all = df_local[df_local['성별'] == '전체']
    plt.figure(figsize=(15,4))
    sns.pointplot(data=df_local_all, x='연도', y='출생아수', hue='시군구별', ci=None)
    plt.legend(loc='center right', bbox_to_anchor=(1.15, 0.5), ncol=1)

    전국적으로 다 줄어들지만 세종특별자치시만 약간씩 증가하는게 보인다

    df_local_2 = df_local_all[df_local_all['시군구별'].isin(['서울특별시', '경기도', '세종특별자치시'])]
    plt.figure(figsize=(15,4))
    sns.pointplot(data=df_local_2, x='연도', y='출생아수', ci=None, hue='시군구별')

    ▶ 세종 특별시만 보자

    df_sj = df[df['시군구별'] == '세종특별자치시'].dropna(how='any')
    
    plt.figure(figsize=(15,4))
    sns.pointplot(data=df_sj, x='연도', y='출생아수', ci=None, hue='시군구별', estimator=np.sum)

    많이 증가했다가 다시 19년부터 줄어들고 있다

     

     

     

     

     

     

     

Designed by Tistory.