자료분석– 저출산자료 시각화
강의영상
https://youtube.com/playlist?list=PLQqh36zP38-ySZ1qjl8-3RrHjoFNetGMG
imports
자료분석: 저출산
데이터읽기 // pd.read_html()
-
대한민국의 저출산문제
- ref: https://ko.wikipedia.org/wiki/대한민국의_저출산
-
위의 url에서 3,5번째 테이블을 읽고싶다. - 3번째 테이블: 시도별 출산율 - 5번째 테이블: 시도별 출생아 수
지역/연도[6] | 2005 | 2006[7] | 2007 | 2008[8] | 2009[9] | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 서울 | 0.92 | 0.97 | 1.06 | 1.01 | 0.96 | 1.02 | 1.01 | 1.06 | 0.97 | 0.98 | 1.00 | 0.94 | 0.84 | 0.76 | 0.72 | 0.64 | 0.63 |
1 | 부산 | 0.88 | 0.91 | 1.02 | 0.98 | 0.94 | 1.05 | 1.08 | 1.14 | 1.05 | 1.09 | 1.14 | 1.10 | 0.98 | 0.90 | 0.83 | 0.75 | 0.73 |
2 | 대구 | 0.99 | 1.00 | 1.13 | 1.07 | 1.03 | 1.11 | 1.15 | 1.22 | 1.13 | 1.17 | 1.22 | 1.19 | 1.07 | 0.99 | 0.93 | 0.81 | 0.78 |
3 | 인천 | 1.07 | 1.11 | 1.25 | 1.19 | 1.14 | 1.21 | 1.23 | 1.30 | 1.20 | 1.21 | 1.22 | 1.14 | 1.01 | 1.01 | 0.94 | 0.83 | 0.78 |
4 | 광주 | 1.10 | 1.14 | 1.26 | 1.20 | 1.14 | 1.22 | 1.23 | 1.30 | 1.17 | 1.20 | 1.21 | 1.17 | 1.05 | 0.97 | 0.91 | 0.81 | 0.90 |
5 | 대전 | 1.10 | 1.15 | 1.27 | 1.22 | 1.16 | 1.21 | 1.26 | 1.32 | 1.23 | 1.25 | 1.28 | 1.19 | 1.08 | 0.95 | 0.88 | 0.81 | 0.81 |
6 | 울산 | 1.18 | 1.24 | 1.40 | 1.34 | 1.31 | 1.37 | 1.39 | 1.48 | 1.39 | 1.44 | 1.49 | 1.42 | 1.26 | 1.13 | 1.08 | 0.99 | 0.94 |
7 | 세종 | - | - | - | - | - | - | - | 1.60 | 1.44 | 1.35 | 1.89 | 1.82 | 1.67 | 1.57 | 1.47 | 1.28 | 1.28 |
8 | 경기 | 1.17 | 1.23 | 1.35 | 1.29 | 1.23 | 1.31 | 1.31 | 1.36 | 1.23 | 1.24 | 1.27 | 1.19 | 1.07 | 1.00 | 0.94 | 0.88 | 0.85 |
9 | 강원 | 1.18 | 1.19 | 1.35 | 1.25 | 1.25 | 1.31 | 1.34 | 1.37 | 1.25 | 1.25 | 1.31 | 1.24 | 1.12 | 1.07 | 1.08 | 1.04 | 0.98 |
10 | 충북 | 1.19 | 1.22 | 1.39 | 1.32 | 1.32 | 1.40 | 1.43 | 1.49 | 1.37 | 1.36 | 1.41 | 1.36 | 1.24 | 1.17 | 1.05 | 0.98 | 0.95 |
11 | 충남 | 1.26 | 1.35 | 1.50 | 1.44 | 1.41 | 1.48 | 1.50 | 1.57 | 1.44 | 1.42 | 1.48 | 1.40 | 1.28 | 1.19 | 1.11 | 1.03 | 0.96 |
12 | 전북 | 1.17 | 1.20 | 1.37 | 1.31 | 1.28 | 1.37 | 1.41 | 1.44 | 1.32 | 1.33 | 1.35 | 1.25 | 1.15 | 1.04 | 0.97 | 0.91 | 0.85 |
13 | 전남 | 1.28 | 1.33 | 1.53 | 1.45 | 1.45 | 1.54 | 1.57 | 1.64 | 1.52 | 1.50 | 1.55 | 1.47 | 1.33 | 1.24 | 1.23 | 1.15 | 1.02 |
14 | 경북 | 1.17 | 1.20 | 1.36 | 1.31 | 1.27 | 1.38 | 1.43 | 1.49 | 1.38 | 1.41 | 1.46 | 1.40 | 1.26 | 1.17 | 1.09 | 1.00 | 0.97 |
15 | 경남 | 1.18 | 1.25 | 1.43 | 1.37 | 1.32 | 1.41 | 1.45 | 1.50 | 1.37 | 1.41 | 1.44 | 1.36 | 1.23 | 1.12 | 1.05 | 0.95 | 0.90 |
16 | 제주 | 1.30 | 1.36 | 1.48 | 1.39 | 1.38 | 1.46 | 1.49 | 1.60 | 1.43 | 1.48 | 1.48 | 1.43 | 1.31 | 1.22 | 1.15 | 1.02 | 0.95 |
17 | 전국 | 1.08 | 1.13 | 1.25 | 1.19 | 1.15 | 1.23 | 1.24 | 1.30 | 1.19 | 1.21 | 1.24 | 1.17 | 1.05 | 0.98 | 0.92 | 0.84 | 0.81 |
지역/연도[6] | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 서울 | 93266 | 91526 | 93914.000 | 84066.000 | 83711.000 | 83005 | 75.536 | 65389 | 58074 | 53.673 | 47400 | 45531 |
1 | 부산 | 27415 | 27759 | 28673.000 | 25831.000 | 26190.000 | 26645 | 24906.000 | 21480 | 19152 | 17049.000 | 15100 | 14446 |
2 | 대구 | 20557 | 20758 | 21472.000 | 19340.000 | 19361.000 | 19438 | 18298.000 | 15946 | 14400 | 13233.000 | 11200 | 10661 |
3 | 인천 | 25752 | 20758 | 21472.000 | 25560.000 | 25786.000 | 25491 | 23609.000 | 20445 | 20087 | 18522.000 | 16000 | 14947 |
4 | 광주 | 13979 | 13916 | 14392.000 | 12729.000 | 12729.000 | 12441 | 11580.000 | 10120 | 9105 | 8364.000 | 7300 | 7956 |
5 | 대전 | 14314 | 14808 | 15279.000 | 14099.000 | 13962.000 | 13774 | 12436.000 | 10851 | 9337 | 8410.000 | 7500 | 7414 |
6 | 울산 | 11432 | 11542 | 12160.000 | 11330.000 | 11556.000 | 11732 | 10910.000 | 9381 | 8149 | 7539.000 | 6600 | 6127 |
7 | 세종 | - | - | 1054.000 | 1111.000 | 1344.000 | 2708 | 3297.000 | 3504 | 3703 | 3819.000 | 3500 | 3570 |
8 | 경기 | 121753 | 122027 | 124746.000 | 112129.000 | 112.169 | 113495 | 105643.000 | 94088 | 83198 | 83.198 | 77800 | 76139 |
9 | 강원 | 12477 | 12408 | 12426.000 | 10980.000 | 10662.000 | 10929 | 10058.000 | 9958 | 8351 | 8283.000 | 7800 | 7357 |
10 | 충북 | 14670 | 14804 | 15139.000 | 13658.000 | 13366.000 | 13563 | 12742.000 | 11394 | 10586 | 9333.000 | 8600 | 8190 |
11 | 충남 | 20.242 | 20.398 | 20.448 | 18.628 | 18200.000 | 18604 | 17302.000 | 15670 | 14380 | 13228.000 | 11900 | 10984 |
12 | 전북 | 16100 | 16175 | 16238.000 | 14555.000 | 14231.000 | 14087 | 12698.000 | 11348 | 10001 | 8971.000 | 8200 | 7745 |
13 | 전남 | 16654 | 16612 | 16990.000 | 15401.000 | 14817.000 | 15061 | 13980.000 | 12354 | 11238 | 10832.000 | 9700 | 8430 |
14 | 경북 | 23700 | 24250 | 24635.000 | 22206.000 | 22062.000 | 22310 | 20616.000 | 17957 | 16079 | 14472.000 | 12900 | 12045 |
15 | 경남 | 32203 | 32536 | 33211.000 | 29504.000 | 29763.000 | 29537 | 27138.000 | 23849 | 21224 | 19250.000 | 16800 | 15562 |
16 | 제주 | 5657 | 5628 | 5992.000 | 5328.000 | 5526.000 | 5600 | 5494.000 | 5037 | 4781 | 4500.000 | 4000 | 3728 |
17 | 전국 | 470171 | 471265 | 484550.000 | 436455.000 | 435435.000 | 438420 | 406243.000 | 357771 | 326822 | 302676.000 | 272400 | 260562 |
-
데이터정리
df1 = _df1.drop(17)\
.melt(id_vars='지역/연도[6]')\
.assign(variable = lambda df: list(map(lambda x: x[:4], df.variable)))\
.assign(value = lambda df: list(map(lambda x: None if x=='-' else float(x), df.value)))\
.set_axis(['지역','연도','출산율'],axis=1)
df1
지역 | 연도 | 출산율 | |
---|---|---|---|
0 | 서울 | 2005 | 0.92 |
1 | 부산 | 2005 | 0.88 |
2 | 대구 | 2005 | 0.99 |
3 | 인천 | 2005 | 1.07 |
4 | 광주 | 2005 | 1.10 |
... | ... | ... | ... |
284 | 전북 | 2021 | 0.85 |
285 | 전남 | 2021 | 1.02 |
286 | 경북 | 2021 | 0.97 |
287 | 경남 | 2021 | 0.90 |
288 | 제주 | 2021 | 0.95 |
289 rows × 3 columns
df2 = _df2.drop(17)\
.melt(id_vars='지역/연도[6]')\
.assign(value = lambda df: list(map(lambda x: None if x=='-' else float(x), df.value)))\
.set_axis(['지역','연도','출생아수'],axis=1)
df2
지역 | 연도 | 출생아수 | |
---|---|---|---|
0 | 서울 | 2010 | 93266.0 |
1 | 부산 | 2010 | 27415.0 |
2 | 대구 | 2010 | 20557.0 |
3 | 인천 | 2010 | 25752.0 |
4 | 광주 | 2010 | 13979.0 |
... | ... | ... | ... |
199 | 전북 | 2021 | 7745.0 |
200 | 전남 | 2021 | 8430.0 |
201 | 경북 | 2021 | 12045.0 |
202 | 경남 | 2021 | 15562.0 |
203 | 제주 | 2021 | 3728.0 |
204 rows × 3 columns
시각화I: 전국 출생아수 시각화
- 일괄적으로 감소하는 느낌은 없음
시각화II: 시도별 출생아수 시각화
-
시각화예시1
- 서울과 경기가 특이함
-
시각화예시2
- areaplot의 최상단의 선: 전국출생아수 시각화와 같음 (일괄적으로 감소하는 느낌은 별로 없음, 그 이유를 살펴보니 서울과 경기지역 떄문임)
- areaplot의 장점: 전국출생아수를 년도별로 시각화 하는 느낌 + 각 연도를 도시별로 분해하여 해석하는 느낌
시각화III: 시도별 출산율 시각화
- 상식과 일치하는 정상적인 플랏 (출산율이 2012년 이후로 꺽이는 느낌이 든다)
- 여기서는 서울/경기가 정상인듯 보인다.
출산율의 경우 합계출산율이 크게 의미가 없으므로 areaplot은 생략한다.
해석
-
이상한점: 서울/경기지역에서 특정연도의 출생아수가 매우 낮음. 그런데 서울/경기지역의 출산율은 모든 년도에서 고른값을 가짐.
-
해석: 데이터가 이상하다.. // 위키를 살펴보니 오타가 있음!!
데이터의 수정 (1): df2 상태에서 수정
-
df2의 수정
지역 | 연도 | 출생아수 | |
---|---|---|---|
62 | 충남 | 2013 | 18.628 |
11 | 충남 | 2010 | 20.242 |
28 | 충남 | 2011 | 20.398 |
45 | 충남 | 2012 | 20.448 |
153 | 서울 | 2019 | 53.673 |
102 | 서울 | 2016 | 75.536 |
161 | 경기 | 2019 | 83.198 |
76 | 경기 | 2014 | 112.169 |
41 | 세종 | 2012 | 1054.000 |
58 | 세종 | 2013 | 1111.000 |
-
오타로 예상되는 서울/경기/충남 이외의 가장 작은 값은 2012년 세종시인데, 이 값이 1054로 1000보다 크다.
- 출생아수 < 1000 이면 출생아수 * 1000 을 수행하는 함수를 구현하자.
지역 | 연도 | 출생아수 | |
---|---|---|---|
0 | 서울 | 2010 | 93266.0 |
1 | 부산 | 2010 | 27415.0 |
2 | 대구 | 2010 | 20557.0 |
3 | 인천 | 2010 | 25752.0 |
4 | 광주 | 2010 | 13979.0 |
... | ... | ... | ... |
199 | 전북 | 2021 | 7745.0 |
200 | 전남 | 2021 | 8430.0 |
201 | 경북 | 2021 | 12045.0 |
202 | 경남 | 2021 | 15562.0 |
203 | 제주 | 2021 | 3728.0 |
204 rows × 3 columns
-
잘 변환되었는지 확인하기 위한 시각화
df2.assign(출생아수= list(map(lambda x: x*1000 if x<1000 else x, df2.출생아수)))\
.plot.area(x='연도',y='출생아수',color='지역',backend='plotly')
- 상식적인 결과: 전체출산율이 점점 낮아지고 있고 항목별로 살펴보아도 모든 도시의 출생아수가 점차 낮아지고 있음
데이터의 수정 (2): _df2 상태에서 수정
-
applymap
2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
지역/연도[6] | ||||||||||||
서울 | 93266 | 91526 | 93914.000 | 84066.000 | 83711.000 | 83005 | 75.536 | 65389 | 58074 | 53.673 | 47400 | 45531 |
부산 | 27415 | 27759 | 28673.000 | 25831.000 | 26190.000 | 26645 | 24906.000 | 21480 | 19152 | 17049.000 | 15100 | 14446 |
대구 | 20557 | 20758 | 21472.000 | 19340.000 | 19361.000 | 19438 | 18298.000 | 15946 | 14400 | 13233.000 | 11200 | 10661 |
인천 | 25752 | 20758 | 21472.000 | 25560.000 | 25786.000 | 25491 | 23609.000 | 20445 | 20087 | 18522.000 | 16000 | 14947 |
광주 | 13979 | 13916 | 14392.000 | 12729.000 | 12729.000 | 12441 | 11580.000 | 10120 | 9105 | 8364.000 | 7300 | 7956 |
대전 | 14314 | 14808 | 15279.000 | 14099.000 | 13962.000 | 13774 | 12436.000 | 10851 | 9337 | 8410.000 | 7500 | 7414 |
울산 | 11432 | 11542 | 12160.000 | 11330.000 | 11556.000 | 11732 | 10910.000 | 9381 | 8149 | 7539.000 | 6600 | 6127 |
세종 | - | - | 1054.000 | 1111.000 | 1344.000 | 2708 | 3297.000 | 3504 | 3703 | 3819.000 | 3500 | 3570 |
경기 | 121753 | 122027 | 124746.000 | 112129.000 | 112.169 | 113495 | 105643.000 | 94088 | 83198 | 83.198 | 77800 | 76139 |
강원 | 12477 | 12408 | 12426.000 | 10980.000 | 10662.000 | 10929 | 10058.000 | 9958 | 8351 | 8283.000 | 7800 | 7357 |
충북 | 14670 | 14804 | 15139.000 | 13658.000 | 13366.000 | 13563 | 12742.000 | 11394 | 10586 | 9333.000 | 8600 | 8190 |
충남 | 20.242 | 20.398 | 20.448 | 18.628 | 18200.000 | 18604 | 17302.000 | 15670 | 14380 | 13228.000 | 11900 | 10984 |
전북 | 16100 | 16175 | 16238.000 | 14555.000 | 14231.000 | 14087 | 12698.000 | 11348 | 10001 | 8971.000 | 8200 | 7745 |
전남 | 16654 | 16612 | 16990.000 | 15401.000 | 14817.000 | 15061 | 13980.000 | 12354 | 11238 | 10832.000 | 9700 | 8430 |
경북 | 23700 | 24250 | 24635.000 | 22206.000 | 22062.000 | 22310 | 20616.000 | 17957 | 16079 | 14472.000 | 12900 | 12045 |
경남 | 32203 | 32536 | 33211.000 | 29504.000 | 29763.000 | 29537 | 27138.000 | 23849 | 21224 | 19250.000 | 16800 | 15562 |
제주 | 5657 | 5628 | 5992.000 | 5328.000 | 5526.000 | 5600 | 5494.000 | 5037 | 4781 | 4500.000 | 4000 | 3728 |
전국 | 470171 | 471265 | 484550.000 | 436455.000 | 435435.000 | 438420 | 406243.000 | 357771 | 326822 | 302676.000 | 272400 | 260562 |
-
방법1
_df2.set_index('지역/연도[6]')\
.applymap(lambda x: None if x == '-' else float(x))\
.applymap(lambda x: x*1000 if x<1000 else x)\
.drop('전국')\
.stack().reset_index()
지역/연도[6] | level_1 | 0 | |
---|---|---|---|
0 | 서울 | 2010 | 93266.0 |
1 | 서울 | 2011 | 91526.0 |
2 | 서울 | 2012 | 93914.0 |
3 | 서울 | 2013 | 84066.0 |
4 | 서울 | 2014 | 83711.0 |
... | ... | ... | ... |
197 | 제주 | 2017 | 5037.0 |
198 | 제주 | 2018 | 4781.0 |
199 | 제주 | 2019 | 4500.0 |
200 | 제주 | 2020 | 4000.0 |
201 | 제주 | 2021 | 3728.0 |
202 rows × 3 columns
-
방법2
df2 = _df2.set_index('지역/연도[6]')\
.applymap(lambda x: None if x == '-' else float(x))\
.applymap(lambda x: x*1000 if x<1000 else x)\
.drop('전국')\
.reset_index()\
.melt(id_vars='지역/연도[6]')\
.set_axis(['지역','연도','출생아수'],axis=1)
df2
지역 | 연도 | 출생아수 | |
---|---|---|---|
0 | 서울 | 2010 | 93266.0 |
1 | 부산 | 2010 | 27415.0 |
2 | 대구 | 2010 | 20557.0 |
3 | 인천 | 2010 | 25752.0 |
4 | 광주 | 2010 | 13979.0 |
... | ... | ... | ... |
199 | 전북 | 2021 | 7745.0 |
200 | 전남 | 2021 | 8430.0 |
201 | 경북 | 2021 | 12045.0 |
202 | 경남 | 2021 | 15562.0 |
203 | 제주 | 2021 | 3728.0 |
204 rows × 3 columns
숙제
아래와 같은 통계량을 구하라.
- \(서울_{2010} = \frac{\text{2010년 서울의 출생자 수}}{\text{2010년 출생자수}}, \dots, 서울_{2021} = \frac{\text{2021년 서울의 출생자 수}}{\text{2021년 출생자수}}\)
참고로 계산결과는 [0.198, 0.196, 0.196, 0.193, 0.192, 0.189, 0.186, 0.182, 0.18, 0.177, 0.174, 0.175] 와 같다.
lineplot을 이용하여 아래와 같이 시각화 하라.
(풀이)