프로그래밍/파이썬

데이터 분석 - 실전 데이터 분석(한국복지패널 데이터)

매 석 2023. 1. 13. 17:42
반응형

1. 사전 설치

pip install pyreadstat
  • SPSS, SAS, STATA 등의 다양한 통계 분석을 위해 설치
  • 추가로 vs code에서 jupyter notebook을 사용 중이다.

 

2. "한국복지패널 데이터" 분석 준비

배경 데이터

import pandas as pd
import numpy as np
import seaborn as sns
#데이터 가져오기
raw = pd.read_spss('Koweps_hpwc14_2019_beta2.sav')
#복사본 생성
welfare = raw.copy()
welfare = welfare.rename(
    columns= {'h14_g3':'sex', #성별
              'h14_g4': 'birth', #출생년도
              'h14_g10' : 'marriage_type', #혼인 여부
              'h14_g11' : 'religion', #종교
              'p1402_8aq1' : 'income', #월급
              'h14_eco9' : 'code_job', #직업 코드
              'h14_reg7' : 'code_region'} #지역 코드
)
  • 사용할 패키지 선언 및 데이터를 가져온다.
  • 이후 데이터 복사본을 만들고, 보기 좋게 rename 해준다.

 

3. 변수 검토 및 전처리 및 관계분석

#변수 타입 출력
welfare['sex'].dtypes
#변수 빈도 구하기
welfare['sex'].value_counts()

#확인한 변수를 토대로, 이상치를 nan처리 한다.
welfare['sex']=np.where(welfare['sex']==9, np.nan, welfare['sex'])
welfare['sex'].isna().sum()

#1이면 male, 그 외의 값이면 female로 설정해준 후 빈도를 구한다.
welfare['sex']=np.where(welfare['sex']==1, 'male', 'female')
welfare['sex'].value_counts()

#그래프 출력
sns.countplot(data=welfare, x='sex')

결과 사진

 

 

예시1) 성별에 따른 월급 차이 분석

배경 데이터 + 소스 코드

#이상치 결측 처리
welfare['income']=np.where(welfare['income']==9999, np.nan,welfare['income'])
income_sex=welfare.dropna(subset=['income'])
                          .groupby('sex', as_index=False)
                          .agg(income_mean=('income','mean'))
sns.barplot(data=income_sex, x='sex', y='income_mean')

결과 사진

 

예시2) 나이와 월급의 관계

배경 데이터 + 소스 코드

#이상치 결측 처리
welfare['birth']=np.where(welfare['birth']==9999, np.nan, welfare['birth'])
#연도를 통해 나이로 변환(2019년 데이터이기에 2019년을 기준으로)
welfare=welfare.assign(age=2019-welfare['birth']+1)
#nan값 제거 및 age를 기준으로 월급의 평균을 구함
income_age = welfare.dropna(subset=['income'])
                           .groupby('age')
                           .agg(income_mean=('income','mean'))
#age별로 선 그래프로 출력
sns.lineplot(data=income_age, x='age', y='income_mean')

결과 사진

 

예시3) 연령대에 따른 월급 차이

배경 데이터 + 소스 코드

#결측치를 제거한 age 값 생성
welfare['birth']=np.where(welfare['birth']==9999, np.nan, welfare['birth'])
welfare=welfare.assign(age=2019-welfare['birth']+1)
#30미만, 59이하, 59이상으로 나이를 나눔
welfare = welfare.assign(age2 = np.where(welfare['age']<30, 'young',
                                np.where(welfare['age']<=59, 'middle',
                                                  'old')))
#nan값 제거 후 age2를 기준으로 월급의 평균을 구함
income_age2 = welfare.dropna(subset=['income'])
                             .groupby('age2', as_index=False)
                             .agg(income_mean=('income','mean'))
#young, middle, old 순으로 bar 차트 생성
sns.barplot(data=income_age2, x='age2', y='income_mean', order=['young','middle','old'])

결과 사진

 

예시4) 연령대 및 성별 월급 차이

배경 데이터 + 소스 코드

#결측치를 제거한 sex 값 생성
welfare['sex']=np.where(welfare['sex']==9, np.nan, welfare['sex'])
welfare['sex']=np.where(welfare['sex']==1, 'male', 'female')
#결측치를 제거한 age 값 생성
welfare['birth']=np.where(welfare['birth']==9999, np.nan, welfare['birth'])
welfare=welfare.assign(age=2019-welfare['birth']+1)
#30미만, 59이하, 59이상으로 나이를 나눔
welfare = welfare.assign(age2 = np.where(welfare['age']<30, 'young',
                                np.where(welfare['age']<=59, 'middle',
                                                  'old')))
#연령대와 성별을 기준으로 월급의 평균을 구함
income_sex=welfare.dropna(subset=['income'])
                          .groupby(['age2','sex'], as_index=False)
                          .agg(income_mean=('income','mean'))
#색은 sex를 기준으로 나누고, 순서는 young, middle, old 순으로 출력
sns.barplot(data=income_sex, x='age2', y='income_mean', hue='sex', 
            order=['young','middle','old'])

결과 사진

 

 

예시5) 직업별 월급 차이

배경 데이터 + 소스 코드

#직종 코드를 불러온다.
job_list = pd.read_excel('Koweps_Codebook_2019.xlsx', sheet_name='직종코드')
#공통으로 들어있는 값을 code_job을 기준으로 결합
welfare=welfare.merge(job_list, how='left', on='code_job')
#직업을 기준으로 월급의 평균을 구한다.
income_job = welfare.dropna(subset=['job','income'])
                            .groupby('job',as_index=False)
                            .agg(income_mean=('income','mean'))
#급여 상위 10개의 직업을 저장한다.
top10 = income_job.sort_values('income_mean',ascending=False).head(10)
#폰트를 잘 보이게 하기위해 설정한다.
import matplotlib.pyplot as plt
plt.rcParams.update({'font.family':'Malgun Gothic'})
#상위 10개의 직업을 출력한다.
sns.barplot(data=top10, y='job', x='income_mean')

결과 사진

 

예시6) 성별 직업 빈도

배경 데이터 + 소스 코드

#결측치를 제거한 sex 값 생성
welfare['sex']=np.where(welfare['sex']==9, np.nan, welfare['sex'])
welfare['sex']=np.where(welfare['sex']==1, 'male', 'female')
#직종 코드를 불러온다.
job_list = pd.read_excel('Koweps_Codebook_2019.xlsx', sheet_name='직종코드')
#공통으로 들어있는 값을 code_job을 기준으로 결합
welfare=welfare.merge(job_list, how='left', on='code_job')
#남자 데이터 
male_job = welfare.dropna(subset=['job']).query('sex=="male"')
                          .groupby('job',as_index=False)
                          .agg(n=('job','count'))
                          .sort_values('n',ascending=False).head(10)
#여자 데이터
female_job=welfare.dropna(subset=['job']).query('sex=="female"')
                          .groupby('job',as_index=False)
                          .agg(n=('job','count'))
                          .sort_values('n',ascending=False).head(10)
#각각 출력
sns.barplot(data=male_job, y='job', x='n').set(xlim=(0,500))
sns.barplot(data=female_job, y='job', x='n').set(xlim=(0,500))

결과 사진

(남)

(여)

 

 

예시7) 종교 유무에 따른 이혼율

배경 데이터 + 소스 코드

#종교에 1이면 yes 아니면 no를 저장한다.
welfare['religion']=np.where(welfare['religion']==1, 'yes', 'no')
#marriage에 marriage_type이 1이면 marriage 3이면 divorce 그 외 etc로 저장한다.
welfare['marriage']=np.where(welfare['marriage_type']==1,'marriage',
                             np.where(welfare['marriage_type']==3, 'divorce',
                             'etc'))
#etc가 아닌 값을 종교를 기준으로 빈도의 비율을 구한다.
div_rel = welfare.query('marriage!="etc"')
                        .groupby('religion', as_index=False)['marriage']
                        .value_counts(normalize=True)
#divorce를 추출하여 백분율로 바꾸고, 반올림한다.
div_rel = div_rel.query('marriage=="divorce"')
                       .assign(proportion=div_rel['proportion']*100).round(1)
sns.barplot(data=div_rel, x="religion", y='proportion')

결과 사진

 

예시8) 지역별 연령대 비율

배경 데이터 + 소스 코드

#결측치를 제거한 age 값 생성
welfare['birth']=np.where(welfare['birth']==9999, np.nan, welfare['birth'])
welfare=welfare.assign(age=2019-welfare['birth']+1)
#30미만, 59이하, 59이상으로 나이를 나눔
welfare = welfare.assign(age2 = np.where(welfare['age']<30, 'young',
                                np.where(welfare['age']<=59, 'middle',
                                                  'old')))
#code에 맞게 지역 매칭
region_list = pd.DataFrame({'code_region':[1,2,3,4,5,6,7],
                            'region':['서울','수도권(인천/경기','부산/경남/울산',
                            '대구/경북','대전/충남','강원/충북','광주/전남/전북/제주도']}
                        )
#code_region을 기준으로 매칭
welfare=welfare.merge(region_list, how="left", on="code_region")
#region을 기준으로 나이별 빈도 비율 구하기
region_age2=welfare.groupby('region', as_index=False)['age2']
                            .value_counts(normalize=True)
#백분율로 표시 후 반올림
region_age2=region_age2.assign(proportion=region_age2['proportion']*100).round(1)

#누적 비율로 피벗
pivot_df=region_age2[['region','age2','proportion']]
                     .pivot(index='region',columns='age2',values='proportion')
#연령대 순으로 막대 색 나열
reorder_df=pivot_df.sort_values('old')[['young','middle','old']]
reorder_df.plot.barh(stacked=True)

결과 사진