Do it! 쉽게 배우는 파이썬 데이터 분석

09 데이터 분석 프로젝트
- 한국인의 삶을 파악하라!






목차

09-1 ‘한국복지패널 데이터’ 분석 준비하기(link)

09-2 성별에 따른 월급 차이 - 성별에 따라 월급이 다를까?(link)

09-3 나이와 월급의 관계 - 몇 살 때 월급을 가장 많이 받을까?(link)

09-4 연령대에 따른 월급 차이 - 어떤 연령대의 월급이 가장 많을까?(link)

09-5 연령대 및 성별 월급 차이 - 성별 월급 차이는 연령대별로 다를까?(link)

09-6 직업별 월급 차이 - 어떤 직업이 월급을 가장 많이 받을까?(link)

09-7 성별 직업 빈도 - 성별에 따라 어떤 직업이 가장 많을까?(link)

09-8 종교 유무에 따른 이혼율 - 종교가 있으면 이혼을 덜 할까?(link)

09-9 지역별 연령대 비율 - 어느 지역에 노년층이 많을까?(link)

09-1 ‘한국복지패널 데이터’ 분석 준비하기

한국복지패널 데이터

  • 한국보건사회연구원 발간 조사 자료
  • 전국 7,000여 가구 선정, 2006년부터 매년 추적 조사한 자료
  • 경제활동, 생활실태, 복지욕구 등 천여 개 변수로 구성됨
  • 다양한 분야의 연구자, 정책전문가들이 활용함
  • 엄밀한 절차로 수집되고 다양한 변수가 있으므로 데이터 분석 연습하기 좋은 재료

데이터 분석 준비하기

1. 데이터 준비하기

  • Koweps_hpwc14_2019_beta2.sav 파일을 워킹 디렉터리에 삽입
  • 2020년 발간 복지패널 데이터. 6,331가구, 14,418명의 정보를 담고 있음

2. 패키지 설치 및 로드하기

  • sav: 통계 분석 소프트웨어 SPSS 전용 파일
  • pyreadstat 패키지 설치하면 pandas 패키지를 이용해 불러올 수 있음
(1) 패키지 설치

`pip install pyreadstat`
(2) 패키지 로드
import pandas as pd
import numpy as np
import seaborn as sns

3. 데이터 불러오기

# 데이터 불러오기
raw_welfare = pd.read_spss('Koweps_hpwc14_2019_beta2.sav')

# 복사본 만들기 
welfare = raw_welfare.copy()

4. 데이터 검토하기

welfare             # 앞부분, 뒷부분 출력
welfare.shape       # 행, 열 개수 출력
welfare.info()      # 변수 속성 출력
welfare.describe()  # 요약 통계량
  • 규모가 큰 데이터는 변수명을 쉬운 단어로 바꾸고 분석할 변수를 하나씩 살펴봐야 함

5. 변수명 바꾸기

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'})   #  지역 코드
  • 규모가 큰 조사 자료는 데이터의 특징을 설명해 놓은 코드북(codebook)을 함께 제공함
  • 코드북에 코드로 된 변수명과 값의 의미가 설명되어 있음
  • 데이터의 특징을 알 수 있고 분석 방향 아이디어를 얻을 수 있음
  • Koweps_Codebook_2019.xlsx 참고

데이터 분석 절차 살펴보기


1단계 - 변수 검토 및 전처리
  • 분석에 활용할 변수 전처리
    • 변수의 특징 파악, 이상치와 결측치 정제
    • 변수의 값을 다루기 편하게 바꾸기
  • 분석에 활용할 변수 각각 전처리
    • ex) 성별에 따른 월급 차이: 성별, 월급 각각
2단계 - 변수 간 관계 분석
  • 변수 간 관계 분석
    • 데이터 요약 표, 그래프 만들기
    • 분석 결과 해석


09-2 성별에 따른 월급 차이
- 성별에 따라 월급이 다를까?

성별 변수 검토 및 전처리하기

1. 변수 검토하기

welfare['sex'].dtypes  # 변수 타입 출력
dtype('float64')
welfare['sex'].value_counts()  # 빈도 구하기
sex
2.0    7913
1.0    6505
Name: count, dtype: int64

2. 전처리하기

# 이상치 확인
welfare['sex'].value_counts()
sex
2.0    7913
1.0    6505
Name: count, dtype: int64
# 이상치 결측 처리
welfare['sex'] = np.where(welfare['sex'] == 9, np.nan, welfare['sex'])

# 결측치 확인
welfare['sex'].isna().sum()
0
# 성별 항목 이름 부여
welfare['sex'] = np.where(welfare['sex'] == 1, 'male', 'female')

# 빈도 구하기
welfare['sex'].value_counts()
sex
female    7913
male      6505
Name: count, dtype: int64
# 빈도 막대 그래프 만들기
sns.countplot(data = welfare, x = 'sex')

월급 변수 검토 및 전처리하기

1. 변수 검토하기

welfare['income'].dtypes  # 변수 타입 출력
dtype('float64')
welfare['income'].describe()  # 요약 통계량 구하기
count    4534.000000
mean      268.455007
std       198.021206
min         0.000000
25%       150.000000
50%       220.000000
75%       345.750000
max      1892.000000
Name: income, dtype: float64
sns.histplot(data = welfare, x = 'income')  # 히스토그램 만들기

2. 전처리하기

welfare['income'].describe()  # 이상치 확인
count    4534.000000
mean      268.455007
std       198.021206
min         0.000000
25%       150.000000
50%       220.000000
75%       345.750000
max      1892.000000
Name: income, dtype: float64
welfare['income'].isna().sum()  # 결측치 확인
9884
# 이상치 결측 처리
welfare['income'] = np.where(welfare['income'] == 9999, np.nan, welfare['income'])

# 결측치 확인
welfare['income'].isna().sum()
9884

성별에 따른 월급 차이 분석하기

1. 성별 월급 평균표 만들기

## 성별 월급 평균표 만들기
sex_income = welfare.dropna(subset = 'income') \
                    .groupby('sex', as_index = False) \
                    .agg(mean_income = ('income', 'mean'))
sex_income

# income 결측치 제거
# sex별 분리
# income 평균 구하기

      sex  mean_income
0  female   186.293096
1    male   349.037571

2. 그래프 만들기

# 막대 그래프 만들기
sns.barplot(data = sex_income, x = 'sex', y = 'mean_income')

09-3 나이와 월급의 관계
- 몇 살 때 월급을 가장 많이 받을까?

나이 변수 검토 및 전처리하기

1. 변수 검토하기

welfare['birth'].dtypes  # 변수 타입 출력
dtype('float64')
welfare['birth'].describe()  # 요약 통계량 구하기
count    14418.000000
mean      1969.280205
std         24.402250
min       1907.000000
25%       1948.000000
50%       1968.000000
75%       1990.000000
max       2018.000000
Name: birth, dtype: float64
sns.histplot(data = welfare, x = 'birth')  # 히스토그램 만들기

2. 전처리하기

welfare['birth'].describe()  # 이상치 확인
count    14418.000000
mean      1969.280205
std         24.402250
min       1907.000000
25%       1948.000000
50%       1968.000000
75%       1990.000000
max       2018.000000
Name: birth, dtype: float64
welfare['birth'].isna().sum()  # 결측치 확인
0
# 이상치 결측 처리
welfare['birth'] = np.where(welfare['birth'] == 9999, np.nan, welfare['birth'])

# 결측치 확인
welfare['birth'].isna().sum()
0

3. 파생변수 만들기 - 나이

welfare = welfare.assign(age = 2019 - welfare['birth'] + 1)  # 나이 변수 만들기
welfare['age'].describe()                                    # 요약 통계량 구하기
count    14418.000000
mean        50.719795
std         24.402250
min          2.000000
25%         30.000000
50%         52.000000
75%         72.000000
max        113.000000
Name: age, dtype: float64
sns.histplot(data = welfare, x = 'age')  # 히스토그램 만들기

나이와 월급의 관계 분석하기

1. 나이에 따른 월급 평균표 만들기

# 나이별 월급 평균표 만들기
age_income = welfare.dropna(subset = 'income') \
                    .groupby('age') \
                    .agg(mean_income = ('income', 'mean'))

age_income.head()

# income 결측치 제거
# age별 분리
# income 평균 구하기

      mean_income
age              
19.0   162.000000
20.0   121.333333
21.0   136.400000
22.0   123.666667
23.0   179.676471

2. 그래프 만들기

# 선 그래프 만들기
sns.lineplot(data = age_income, x = 'age', y = 'mean_income')

09-4 연령대에 따른 월급 차이
- 어떤 연령대의 월급이 가장 많을까?

연령대 변수 검토 및 전처리하기

파생변수 만들기 - 연령대

# 나이 변수 살펴보기
welfare['age'].head()
0    75.0
1    72.0
2    78.0
3    58.0
4    57.0
Name: age, dtype: float64
# 연령대 변수 만들기
welfare = welfare.assign(ageg = np.where(welfare['age'] <  30, 'young',
                                np.where(welfare['age'] <= 59, 'middle', 'old')))

# 빈도 구하기
welfare['ageg'].value_counts()
ageg
old       5955
middle    4963
young     3500
Name: count, dtype: int64
# 빈도 막대 그래프 만들기
sns.countplot(data = welfare, x = 'ageg')

연령대에 따른 월급 차이 분석하기

1. 연령대별 월급 평균표 만들기

# 연령대별 월급 평균표 만들기
ageg_income = welfare.dropna(subset = 'income') \
                     .groupby('ageg', as_index = False) \
                     .agg(mean_income = ('income', 'mean'))
ageg_income

# income 결측치 제거
# ageg별 분리
# income 평균 구하기

     ageg  mean_income
0  middle   329.157157
1     old   140.129003
2   young   195.663424

2. 그래프 만들기

# 막대 그래프 만들기
sns.barplot(data = ageg_income, x = 'ageg', y = 'mean_income')

# 막대 정렬하기
sns.barplot(data = ageg_income, x = 'ageg', y = 'mean_income',
            order = ['young', 'middle', 'old'])

09-5 연령대 및 성별 월급 차이
- 성별 월급 차이는 연령대별로 다를까?

연령대 및 성별 월급 차이 분석하기

1. 연령대 및 성별 월급 평균표 만들기

# 연령대 및 성별 평균표 만들기
sex_income = welfare.dropna(subset = 'income') \
                    .groupby(['ageg', 'sex'], as_index = False) \
                    .agg(mean_income = ('income', 'mean'))
sex_income

# income 결측치 제거
# ageg 및 sex별 분리
# income 평균 구하기

     ageg     sex  mean_income
0  middle  female   230.481735
1  middle    male   409.541228
2     old  female    90.228896
3     old    male   204.570231
4   young  female   189.822222
5   young    male   204.909548

2. 그래프 만들기

# 막대 그래프 만들기
sns.barplot(data = sex_income, x = 'ageg', y = 'mean_income', hue = 'sex',
            order = ['young', 'middle', 'old'])

나이 및 성별 월급 차이 분석하기

# 나이 및 성별 월급 평균표 만들기
sex_age = welfare.dropna(subset = 'income') \
                 .groupby(['age', 'sex'], as_index = False) \
                 .agg(mean_income = ('income', 'mean'))
sex_age.head()

# income 결측치 제거
# age 및 sex별 분리
# income 평균 구하기

    age     sex  mean_income
0  19.0    male   162.000000
1  20.0  female    87.666667
2  20.0    male   155.000000
3  21.0  female   124.000000
4  21.0    male   186.000000
# 선 그래프 만들기
sns.lineplot(data = sex_age, x = 'age', y = 'mean_income', hue = 'sex')

09-6 직업별 월급 차이
- 어떤 직업이 월급을 가장 많이 받을까?

직업 변수 검토 및 전처리하기

1. 변수 검토하기

welfare['code_job'].dtypes  # 변수 타입 출력
dtype('float64')
welfare['code_job'].value_counts()  # 빈도 구하기
code_job
611.0    962
941.0    391
521.0    354
312.0    275
873.0    236
        ... 
112.0      2
784.0      2
423.0      1
861.0      1
872.0      1
Name: count, dtype: int64

2. 전처리하기

list_job = pd.read_excel('Koweps_Codebook_2019.xlsx', sheet_name = '직종코드')
list_job.head()
   code_job                                     job
0       111  의회 의원∙고위 공무원 및 공공단체 임원
1       112                          기업 고위 임원
2       121                행정 및 경영 지원 관리자
3       122              마케팅 및 광고∙홍보 관리자
4       131           연구∙교육 및 법률 관련 관리자
list_job.shape  # 행, 열 개수 출력
(156, 2)
# welfare에 list_job 결합하기
welfare = welfare.merge(list_job, how = 'left', on = 'code_job')

# code_job 결측치 제거하고 code_job, job 출력
welfare.dropna(subset = ['code_job'])[['code_job', 'job']].head()
    code_job                           job
2      762.0                        전기공
3      855.0          금속기계 부품 조립원
7      941.0          청소원 및 환경미화원
8      999.0  기타 서비스 관련 단순 종사자
14     312.0              경영 관련 사무원

직업별 월급 차이 분석하기

1. 직업별 월급 평균표 만들기

# 직업별 월급 평균표 만들기
job_income = welfare.dropna(subset = ['job', 'income']) \
                    .groupby('job', as_index = False) \
                    .agg(mean_income = ('income', 'mean'))
job_income.head()

# job, income 결측치 제거
# job별 분리
# income 평균 구하기
                              job  mean_income
0             가사 및 육아 도우미    92.455882
1                          간호사   265.219178
2  감정∙기술영업및중개관련종사자    391.000000
3           건물 관리원 및 검표원   168.375000
4        건설 및 광업 단순 종사자   261.975000

3. 그래프 만들기

(1) 월급이 많은 직업

# 상위 10위 추출
top10 = job_income.sort_values('mean_income', ascending = False).head(10)
top10
                                        job  mean_income
98                         의료 진료 전문가   781.000000
60                              법률 전문가   776.333333
140                행정 및 경영 지원 관리자   771.833333
63                      보험 및 금융 관리자   734.750000
110            재활용 처리 및 소각로 조작원   688.000000
131      컴퓨터 하드웨어 및 통신공학 전문가   679.444444
24           기계∙로봇공학 기술자 및 시험원   669.166667
6             건설∙전기 및 생산 관련 관리자   603.083333
120                        제관원 및 판금원   597.000000
100  의회 의원∙고위 공무원 및 공공단체 임원   580.500000
# 맑은 고딕 폰트 설정
import matplotlib.pyplot as plt
plt.rcParams.update({'font.family' : 'Malgun Gothic'})

# 막대 그래프 만들기
sns.barplot(data = top10, y = 'job', x = 'mean_income')

(2) 월급이 적은 직업

# 하위 10위 추출
bottom10 = job_income.sort_values('mean_income').head(10)
bottom10
                                           job  mean_income
33   기타 돌봄∙보건 및 개인 생활 서비스 종사자    73.964286
34                기타 서비스 관련 단순 종사자    77.789474
128                       청소원 및 환경미화원    88.461756
0                          가사 및 육아 도우미    92.455882
43                  돌봄 및 보건 서비스 종사자   117.162338
97                       음식 관련 단순 종사자   118.187500
39                  농림∙어업 관련 단순 종사자   122.625000
139               학예사∙사서 및 기록물 관리사   140.000000
126              채굴 및 토목 관련 기능 종사자   140.000000
135                      판매 관련 단순 종사자   140.909091
# 막대 그래프 만들기
sns.barplot(data = bottom10, y = 'job', x = 'mean_income') \
   .set(xlim = [0, 800])

09-7 성별 직업 빈도
- 성별에 따라 어떤 직업이 가장 많을까?

성별 직업 빈도 분석하기

1. 성별 직업 빈도표 만들기

# 남성 직업 빈도 상위 10개 추출
job_male = welfare.dropna(subset = ['job']) \
                  .query('sex == "male"') \
                  .groupby('job', as_index = False) \
                  .agg(n = ('job', 'count')) \
                  .sort_values('n', ascending = False) \
                  .head(10)
job_male

# job 결측치 제거
# male 추출
# job별 분리
# job 빈도 구하기
# 내림차순 정렬
# 상위 10행 추출

                          job    n
107          작물 재배 종사자  486
104             자동차 운전원  230
11           경영 관련 사무원  216
46           매장 판매 종사자  142
89                영업 종사자  113
127      청소원 및 환경미화원  109
4    건설 및 광업 단순 종사자   96
120     제조 관련 단순 종사자   80
3       건물 관리원 및 검표원   79
141               행정 사무원   74

성별 직업 빈도 분석하기

1. 성별 직업 빈도표 만들기

# 여성 직업 빈도 상위 10개 추출
job_female = welfare.dropna(subset = ['job']) \
                    .query('sex == "female"') \
                    .groupby('job', as_index = False) \
                    .agg(n = ('job', 'count')) \
                    .sort_values('n', ascending = False) \
                    .head(10)
job_female

# job 결측치 제거
# female 추출
# job별 분리
# job 빈도 구하기
# 내림차순 정렬
# 상위 10행 추출

                              job    n
83               작물 재배 종사자  476
91           청소원 및 환경미화원  282
33               매장 판매 종사자  212
106           회계 및 경리 사무원  163
31     돌봄 및 보건 서비스 종사자  155
87          제조 관련 단순 종사자  148
73          음식 관련 단순 종사자  126
58           식음료 서비스 종사자  117
88                         조리사  114
24   기타 서비스 관련 단순 종사자   97

2. 그래프 만들기

# 남성 직업 빈도 막대 그래프 만들기
sns.barplot(data = job_male, y = 'job', x = 'n').set(xlim = [0, 500])

2. 그래프 만들기

# 여성 직업 빈도 막대 그래프 만들기
sns.barplot(data = job_female, y = 'job', x = 'n').set(xlim = [0, 500])

09-8 종교 유무에 따른 이혼율
- 종교가 있으면 이혼을 덜 할까?

종교 변수 검토 및 전처리하기

1. 변수 검토하기

welfare['religion'].dtypes  # 변수 타입 출력
dtype('float64')
welfare['religion'].value_counts()  # 빈도 구하기
religion
2.0    7815
1.0    6603
Name: count, dtype: int64

2. 전처리하기

# 종교 유무 이름 부여
welfare['religion'] = np.where(welfare['religion'] == 1, 'yes', 'no')

# 빈도 구하기
welfare['religion'].value_counts()
religion
no     7815
yes    6603
Name: count, dtype: int64
# 막대 그래프 만들기
sns.countplot(data = welfare, x = 'religion')

혼인 상태 변수 검토 및 전처리하기

1. 변수 검토하기

welfare['marriage_type'].dtypes  # 변수 타입 출력
dtype('float64')
welfare['marriage_type'].value_counts()  # 빈도 구하기
marriage_type
1.0    7190
5.0    2357
0.0    2121
2.0    1954
3.0     689
4.0      78
6.0      29
Name: count, dtype: int64

2. 파생변수 만들기 - 이혼 여부

# 이혼 여부 변수 만들기
welfare['marriage'] = np.where(welfare['marriage_type'] == 1, 'marriage',
                      np.where(welfare['marriage_type'] == 3, 'divorce', 'etc'))
# 이혼 여부별 빈도
n_divorce = welfare.groupby('marriage', as_index = False) \
                   .agg(n = ('marriage', 'count'))
n_divorce

# marriage별 분리
# marriage별 빈도 구하기

   marriage     n
0   divorce   689
1       etc  6539
2  marriage  7190
# 막대 그래프 만들기
sns.barplot(data = n_divorce, x = 'marriage', y = 'n')

종교 유무에 따른 이혼율 분석하기

1. 종교 유무에 따른 이혼율표 만들기

rel_div = welfare.query('marriage != "etc"') \
                 .groupby('religion', as_index = False) \
                 ['marriage'] \
                 .value_counts(normalize = True)
rel_div
# etc 제외
# religion별 분리
# marriage 추출
# 비율 구하기

  religion  marriage  proportion
0       no  marriage    0.905045
1       no   divorce    0.094955
2      yes  marriage    0.920469
3      yes   divorce    0.079531

2. 그래프 만들기

rel_div = \
    rel_div.query('marriage == "divorce"') \
           .assign(proportion = rel_div['proportion'] * 100) \
           .round(1)

rel_div
# divorce 추출
# 백분율로 바꾸기
# 반올림

  religion marriage  proportion
1       no  divorce         9.5
3      yes  divorce         8.0
# 막대 그래프 만들기
sns.barplot(data = rel_div, x = 'religion', y = 'proportion')

연령대 및 종교 유무에 따른 이혼율 분석하기

1. 연령대별 이혼율표 만들기

age_div = welfare.query('marriage != "etc"') \
                 .groupby('ageg', as_index = False) \
                 ['marriage'] \
                 .value_counts(normalize = True)
age_div
# etc 제외
# ageg별 분리
# marriage 추출
# 비율 구하기

     ageg  marriage  proportion
0  middle  marriage    0.910302
1  middle   divorce    0.089698
2     old  marriage    0.914220
3     old   divorce    0.085780
4   young  marriage    0.950000
5   young   divorce    0.050000
# 연령대 및 이혼 여부별 빈도
welfare.query('marriage != "etc"') \
       .groupby('ageg', as_index = False) \
       ['marriage'] \
       .value_counts()

# etc 제외
# ageg별 분리
# marriage 추출
# 빈도 구하기

     ageg  marriage  count
0  middle  marriage   3552
1  middle   divorce    350
2     old  marriage   3581
3     old   divorce    336
4   young  marriage     57
5   young   divorce      3

2. 연령대별 이혼율 그래프 만들기

age_div = \ 
    age_div.query('ageg != "young" & marriage == "divorce"') \
           .assign(proportion = age_div['proportion'] * 100) \
           .round(1)

age_div
# 초년층 제외, 이혼 추출
# 백분율로 바꾸기
# 반올림

     ageg marriage  proportion
1  middle  divorce         9.0
3     old  divorce         8.6
# 막대 그래프 만들기
sns.barplot(data = age_div, x = 'ageg', y = 'proportion')

3. 연령대 및 종교 유무에 따른 이혼율표 만들기

age_rel_div = \
    welfare.query('marriage != "etc" & ageg != "young"') \
           .groupby(['ageg', 'religion'], as_index = False) \
           ['marriage'] \
           .value_counts(normalize = True)

age_rel_div
# etc 제외, 초년층 제외
# ageg, religion별 분리
# marriage 추출
# 비율 구하기

     ageg religion  marriage  proportion
0  middle       no  marriage    0.904953
1  middle       no   divorce    0.095047
2  middle      yes  marriage    0.917520
3  middle      yes   divorce    0.082480
4     old       no  marriage    0.904382
5     old       no   divorce    0.095618
6     old      yes  marriage    0.922222
7     old      yes   divorce    0.077778

4. 연령대 및 종교 유무에 따른 이혼율 그래프 만들기

age_rel_div = \
    age_rel_div.query('marriage == "divorce"') \
               .assign(proportion = age_rel_div['proportion'] * 100) \
               .round(1)

age_rel_div
# divorce 추출
# 백분율로 바꾸기
# 반올림

     ageg religion marriage  proportion
1  middle       no  divorce         9.5
3  middle      yes  divorce         8.2
5     old       no  divorce         9.6
7     old      yes  divorce         7.8
# 막대 그래프 만들기
sns.barplot(data = age_rel_div, x = 'ageg', y = 'proportion', hue = 'religion')

09-9 지역별 연령대 비율
- 어느 지역에 노년층이 많을까?

지역 변수 검토 및 전처리하기

1. 변수 검토하기

welfare['code_region'].dtypes  # 변수 타입 출력
dtype('float64')
welfare['code_region'].value_counts()  # 빈도 구하기
code_region
2.0    3246
7.0    2466
3.0    2448
1.0    2002
4.0    1728
5.0    1391
6.0    1137
Name: count, dtype: int64

2. 전처리하기

# 지역 코드 목록 만들기
list_region = pd.DataFrame({'code_region' : [1, 2, 3, 4, 5, 6, 7],
                            'region'      : ['서울',
                                             '수도권(인천/경기)',
                                             '부산/경남/울산',
                                             '대구/경북',
                                             '대전/충남',
                                             '강원/충북',
                                             '광주/전남/전북/제주도']})
list_region
   code_region                 region
0            1                   서울
1            2      수도권(인천/경기)
2            3         부산/경남/울산
3            4              대구/경북
4            5              대전/충남
5            6              강원/충북
6            7  광주/전남/전북/제주도
# 지역명 변수 추가
welfare = welfare.merge(list_region, how = 'left', on = 'code_region')
welfare[['code_region', 'region']].head()
   code_region region
0          1.0   서울
1          1.0   서울
2          1.0   서울
3          1.0   서울
4          1.0   서울

지역별 연령대 비율 분석하기

1. 지역별 연령대 비율표 만들기

region_ageg = welfare.groupby('region', as_index = False) \
                     ['ageg'] \
                     .value_counts(normalize = True)
region_ageg
# region별 분리
# ageg 추출
# 비율 구하기

                   region    ageg  proportion
0               강원/충북     old    0.459103
1               강원/충북  middle    0.308707
2               강원/충북   young    0.232190
3   광주/전남/전북/제주도     old    0.449311
4   광주/전남/전북/제주도  middle    0.317924
5   광주/전남/전북/제주도   young    0.232766
6               대구/경북     old    0.504051
7               대구/경북  middle    0.296296
8               대구/경북   young    0.199653
9               대전/충남     old    0.413372
10              대전/충남  middle    0.336449
11              대전/충남   young    0.250180
12         부산/경남/울산     old    0.437500

2. 그래프 만들기

region_ageg = \
    region_ageg.assign(proportion = region_ageg['proportion'] * 100) \
               .round(1)

# 백분율로 바꾸기
# 반올림

# 막대 그래프 만들기
sns.barplot(data = region_ageg, y = 'region', x = 'proportion', hue = 'ageg')

3. 누적 비율 막대 그래프 만들기

(1) 피벗하기
# 피벗
pivot_df = \
    region_ageg[['region', 'ageg', 'proportion']].pivot(index   = 'region',
                                                        columns = 'ageg',
                                                        values  = 'proportion')
pivot_df
ageg                   middle   old  young
region                                    
강원/충북                30.9  45.9   23.2
광주/전남/전북/제주도    31.8  44.9   23.3
대구/경북                29.6  50.4   20.0
대전/충남                33.6  41.3   25.0
부산/경남/울산           33.4  43.8   22.9
서울                     38.5  37.6   23.9
수도권(인천/경기)        38.8  32.5   28.7
(2) 그래프 만들기
# 가로 막대 그래프 만들기
pivot_df.plot.barh(stacked = True)

(3) 막대 정렬하기
# 노년층 비율 기준 정렬, 변수 순서 바꾸기
reorder_df = pivot_df.sort_values('old')[['young', 'middle', 'old']]
reorder_df
ageg                   young  middle   old
region                                    
수도권(인천/경기)       28.7    38.8  32.5
서울                    23.9    38.5  37.6
대전/충남               25.0    33.6  41.3
부산/경남/울산          22.9    33.4  43.8
광주/전남/전북/제주도   23.3    31.8  44.9
강원/충북               23.2    30.9  45.9
대구/경북               20.0    29.6  50.4
# 누적 가로 막대 그래프 만들기
reorder_df.plot.barh(stacked = True)