Learn & Record

Python (선그래프, 폴리움 folium, 히스토그램, 한국복지패널 데이터 분석) 본문

Dev/Python

Python (선그래프, 폴리움 folium, 히스토그램, 한국복지패널 데이터 분석)

Walker_ 2024. 3. 15. 16:50

1. 선 그래프 : 시간에 따라 다라지는 데이터 표현하기

 - 선그래프 : 데이터를 선으로 표현한 그래프

 - 시간에 따라 달라지는 데이터를 표현할 때 자주 사용

 - 예를 들어 환율, 주가 치수 등 경제 지표가 시간에 따라 변하는 양상을 '선 그래프'로 표현

 

 - 시계열 데이터 : 일별 환율처럼, 일정 시간 간격을 두고 나열된 데이터

 - 시계열 그래프 : 시계열 데이터를 선으로 표현한 그래프

 

 - 1) 시계열 그래프 그리기

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

# economic 데이터 불러오기
economics = pd.read_csv('./input/economics.csv')
print(economics.head())

# sns.lineplot()을 이용하면 선 그래프를 만들 수 있음
# x축에는 시간을 나타낸 date, y축에는 실업자 수를 나타낸 unemploy를 지정
sns.lineplot(data=economics, x='date', y='unemploy')
plt.show()

 

# 출력된 그래프를 보면 x축에 굵은 선이 표시되어 있음
# date 변수에는 '1967-07-01'처럼 '연월일'을 나타낸 문자가 있는데,
# 이 값이 x축에 가로로 여러 번 겹쳐 표시되어서 굵은 선으로 보임

# 1) x축에 연도 표시하기
# x축에 연도가 표시되도록 설정
# x축에 연도를 표시하려면 먼저 변수 타입을 날짜 시간 타입 datetime64으로 바꿔야 함,
# economics 데이터의 date가 문자 object 타입으로 되어 있음

# a) 날짜 시간 타입 변수 만들기
# 날짜 시간 타입 변수 만들기
# pd.to_datetime()을 이용하면 변수의 타입을 날짜 시간 타입으로 바꿀 수 있음
# date 타입을 날짜 시간 타입으로 변경해서 date2 변수 추가
economics['date2'] = pd.to_datetime(economics['date'])

# 변수 타입 확인
print(economics.info())
#  #   Column    Non-Null Count  Dtype
# ---  ------    --------------  -----
#  0   date      574 non-null    object
#  1   pce       574 non-null    float64
#  2   pop       574 non-null    float64
#  3   psavert   574 non-null    float64
#  4   uempmed   574 non-null    float64
#  5   unemploy  574 non-null    int64
#  6   date2     574 non-null    datetime64[ns]
# dtypes: datetime64[ns](1), float64(4), int64(1), object(1)
# memory usage: 31.5+ KB

# date 열은 object 타입이고 datetime64 타입인 date2 열 추가 확인

# 변수의 타입을 날짜 시간 타입으로 바꾸더라도 값이 달라지지 않음
print(economics[['date', 'date2']].head())
#          date      date2
# 0  1967-07-01 1967-07-01
# 1  1967-08-01 1967-08-01
# 2  1967-09-01 1967-09-01
# 3  1967-10-01 1967-10-01
# 4  1967-11-01 1967-11-01

# 출력 결과를 보면 두 변수의 값이 같음
# date2 변수는 날짜 시간 타입으로 되어 있어서 df.dt를 이용해 연,월,일을 추출할 수 있음
# 연 추출
print(economics['date2'].dt.year.head())
#          date      date2
# 0  1967-07-01 1967-07-01
# 1  1967-08-01 1967-08-01
# 2  1967-09-01 1967-09-01
# 3  1967-10-01 1967-10-01
# 4  1967-11-01 1967-11-01
# 0    1967
# 1    1967
# 2    1967
# 3    1967
# 4    1967
# Name: date2, dtype: int32

# 월 추출
print(economics['date2'].dt.month.head())
# Name: date2, dtype: int32
# 0     7
# 1     8
# 2     9
# 3    10
# 4    11
# Name: date2, dtype: int32

# 일 추출
print(economics['date2'].dt.day.head())
# Name: date2, dtype: int32
# 0    1
# 1    1
# 2    1
# 3    1
# 4    1
# Name: date2, dtype: int32

# b) 연도 변수 만들기
# economics에 년도를 나타낸 변수 year를 추가

# 연도 변수 추가
economics['year'] = economics['date2'].dt.year
print(economics.head())
#          date    pce       pop  psavert  uempmed  unemploy      date2  year
# 0  1967-07-01  506.7  198712.0     12.6      4.5      2944 1967-07-01  1967
# 1  1967-08-01  509.8  198911.0     12.6      4.7      2945 1967-08-01  1967
# 2  1967-09-01  515.6  199113.0     11.9      4.6      2958 1967-09-01  1967
# 3  1967-10-01  512.2  199311.0     12.9      4.9      3143 1967-10-01  1967
# 4  1967-11-01  517.4  199498.0     12.8      4.7      3066 1967-11-01  1967

print(economics.info())
#  #   Column    Non-Null Count  Dtype
# ---  ------    --------------  -----
#  0   date      574 non-null    object
#  1   pce       574 non-null    float64
#  2   pop       574 non-null    float64
#  3   psavert   574 non-null    float64
#  4   uempmed   574 non-null    float64
#  5   unemploy  574 non-null    int64
#  6   date2     574 non-null    datetime64[ns]
#  7   year      574 non-null    int32
# dtypes: datetime64[ns](1), float64(4), int32(1), int64(1), object(1)
# memory usage: 33.8+ KB
# None

# c) x축에 연도 표시하기
# 연도를 나타낸 변수를 sns.lineplot()의 x에 입력하면 x축에 연도가 표시

# x축에 연도 표시
sns.lineplot(data=economics, x='year', y='unemploy')
plt.show()

 

# 선의 위아래에 표시된 면적은 신뢰구간 confidence interval
# 신뢰 구간을 표시하지 않을려면 errorbar=None을 입력하면 됨

# 신뢰구간 제거
sns.lineplot(data=economics, x='year', y='unemploy', errorbar=None)
plt.show()
sns.lineplot(data=economics, x='date2', y='unemploy')
plt.show()

 

 

# 연습문제
# 북대구 영업소의 2023년 12월 일자별 총 교통량의 변화를 선그래프로

df1 = pd.read_csv('./input/TCS_B3_04_03_238959.csv', encoding='ANSI')
df4 = df1[df1['영업소명'] == '북대구']
print(df4.tail())

df5 = df4[df4['집계일자'].astype(str).str.contains('2023-12')]
print(df5.head()) # 북대구 12월 데이터

df6 = df5.groupby('집계일자', as_index=False).agg(n=('총교통량', 'sum'))
df6['집계일자'] = pd.to_datetime(df6['집계일자'])
plt.figure(figsize=(20, 6))
sns.lineplot(data=df6, x='집계일자', y='n')
plt.show()
# 코드 일부 놓쳐서 그래프 정보 부족함

 

 

 2. folium 폴리움

 - folium : 라이브러리는 지도 위에 시각화 할 때 유용한 도구

 - 세계 지도를 기본 지원하고 다양한 스타일의 지도 이미지를 제공하고 있음

 

 - https://python-visualization.github.io/folium/latest/

 

Folium — Folium 0.1.dev1+g12b8807 documentation

Folium builds on the data wrangling strengths of the Python ecosystem and the mapping strengths of the Leaflet.js library. Manipulate your data in Python, then visualize it in a Leaflet map via Folium. Concepts Folium makes it easy to visualize data that

python-visualization.github.io

# 1) 지도 만들기
import folium

 

 - folium 라이브러리의 Map() 함수를 이용하면 간단하게 지도 객체를 만들 수 있음

 - 지도 화면은 고정된 것이 아니고 줌 zoom 기능과 화면 이동 Scroll이 가능

 

 - folium은 웹 기반 지도를 만들기 때문에, 웹 환경에서만 지도를 확인 할 수 있음

 - 지도를 보려면 지도 객체에 save() 메서드를 적용하여 HTML 파일로 저장하고,

 - 웹 브라우저에서 파일을 열어서 확인

 - 주피터 노트북에서는 바로 지도 객체를 확인 할 수 있음

 

 - 서울 지도 만들기

 - location 옵션에 [위도, 경도] 수치를 입력하면 그 지점을 중심으로 지도를 보여줌

 - zoom_start 옵션을 사용하면 화면 확대 비율을 조절할 수 있음

seoul_map = folium.Map(location=[37.55, 126.98], zoom_start=12)

# 지도를 HTML 파일로 저장하기
seoul_map.save('./output/seoul_map.html')
# Map() 함수에 tiles 옵션을 적용하면 지도에 적용하는 스타일을 변경하여 지정할 수 있음
import folium

# 기본 값 : OpenStreetMap
# tiles='cartodbpositron' : 단계 구분도가 잘 표현 되도록 밝은 색으로 바꿈

seoul_map2 = folium.Map(location=[37.55, 126.98], zoom_start=15, tiles='Cartodb Positron')
seoul_map2.save('./output/seoul_map2.html')

 

 

seoul_map3 = folium.Map(location=[37.55, 126.98], zoom_start=12, tiles='cartodbpositrononlylabels')
seoul_map3.save('./output/seoul_map3.html')

 

 

# 3) 지도에 마커 표시하기
# 서울 시내 주요 대학교의 위치 데이터를 데이터 프레임으로 변환하고, folium 지도에 위치를 표시

import pandas as pd

# 대학교 리스트를 데이터프레임 변환
df = pd.read_excel('./input/서울지역 대학교 위치.xlsx')
print(df.head())

# 서울 지도 만들기
seoul_map4 = folium.Map(location=[37.55, 126.98], zoom_start=12)

# 대학교 위치정보를 Marker로 표시
for name, lat, lng in zip(df['name'], df['위도'], df['경도']):
    folium.Marker([lat, lng], popup=name).add_to(seoul_map)
seoul_map4.save('./output/seoul_map4.html')

 

 

# 4) 지도에 원형 마커 표시
import pandas as pd
import folium

# 대학교 리스트를 데이터프레임 변환
df = pd.read_excel('./input/서울지역 대학교 위치.xlsx')
print(df.head())

# 서울 지도 만들기
seoul_map5 = folium.Map(location=[37.55, 126.98], zoom_start=12, tiles='Cartodb Positron')

# 대학교 위치정보를 CircleMarker로 표시
# Marker() 대신 CircleMarker()를 사용. 원형 마커의 크기, 색상, 투명도 들을 설정할 수 있음
for name, lat, lng in zip(df['name'], df['위도'], df['경도']):
    folium.CircleMarker((lat, lng), popup=name,
                        raidus = 10,  # 원의 반지름
                        color='brown',
                        fill=True,
                        fill_color='coral',
                        fill_opacity=0.7).add_to(seoul_map5)

seoul_map5.save('./output/seoul_map5.html')

 

 

# 5) 지도 영역에 단계 구분도 Choropleth Map 표시하기
# 행정구역과 같이 지도 상의 어떤 경계에 둘러싸인 영역에 색을 칠하거나 음영 등으로 정보를 나타내는 시각화 방법
# 전달하는 정보의 값이 커지면 영역에 칠해진 색이나 음영이 진해짐

import pandas as pd
import folium
import json


# 경기도 인구변화 데이터를 불려와서 데이터프레임으로 변환
# 경기도 지역의 시군구별 인구변화 데이터 (2007 ~ 2017)

df = pd.read_excel('./input/경기도인구데이터.xlsx', index_col='구분')
print(df.head())

df.columns = df.columns.map(str)

# 경기도 시군구 경계 정보를 가진 geo-json 파일 불러오기
# 경기도 행정구역  경계 지리 정보를 사용

geo_path = './input/경기도행정구역경계.json'
geo_data = json.load(open(geo_path, encoding='utf-8-sig'))
pprint.pprint(geo_data)
# 경기도 지도 만들기
g_map = folium.Map(location=[37.5502, 126.982], zoom_start=9)

# 출력할 연도 선택
year = '2017'

folium.Choropleth(geo_data=geo_data, # 지도 통계
                  data=df[year], # 표시하려는 데이터
                  columns=[df.index, df[year]], # 열 지정
                  fill_color='YlOrRd', fill_opacity=0.7, line_opacity=0.3,
                  threshold_scale=[10000, 100000, 300000, 500000, 700000],
                  key_on = 'feature.properties.name',
                  ).add_to(g_map)

g_map.save('./output/g_map.html')

 

 

# 연습문제
# 필요한 정보만 데이터프레임으로 변경
# 남구, 달서구, 상권업종중분류명 : 이용,미용 지도에 표시

df = pd.read_csv('./input/소상공인시장진흥공단_상가(상권)정보_대구_202312.csv')
print(df.head())
print(df.info())

# 원하는 정보만 추출
df2 = df[['상호명', '상권업종중분류명', '시군구명', '위도', '경도']]
df3 = df2.loc[((df2['시군구명']== '남구') | (df2['시군구명'] == '달서구')) & (df2['상권업종중분류명'] == '이용·미용')]
print(df3.head())

# 대구 지도만들기 128.571230303876,35.8334982682276
daegu_map = folium.Map(location=[35.83,128.56], zoom_start=12)

for name, lat, lng in zip(df3['상호명'], df3['위도'], df3['경도']):
    folium.Marker((lat, lng), popup=name).add_to(daegu_map)

daegu_map.save('./output/daegu_map.html')

 

 

# 연습문제 2
# 경북 데이터 이용
# 필요한 정보만 데이터 프레임으로 변경
# 경산, 표준산업분류명: 커피전문점 지도에 표시

df = pd.read_csv('./input/소상공인시장진흥공단_상가(상권)정보_경북_202312.csv')

# 원하는 정보만 추출
df2 = df[['상호명', '표준산업분류명', '시군구명', '위도', '경도']]
df3 = df2[(df2['표준산업분류명'] == '커피 전문점') & (df2['시군구명'] == '경산시')]
print(df3.head())

# 경산 지도 만들기
gs_map = folium.Map(location=[35.82, 128.74], zoom_start= 12)

for name, lat, lng in zip(df3['상호명'], df3['위도'], df3['경도']):
    tooltip = folium.Tooltip(name, permanent= True)
    folium.CircleMarker((lat, lng), tooltip=tooltip).add_to(gs_map)

gs_map.save('./output/gs_map.html')

 

 

3. 히스토그램

 - 히스토그램 histogram은 데이터를 정해진 간격으로 나눈 후 그 간격 안에 들어간 데이터 갯수를 막대로 표시한 그래프

 - 주로 데이터가 어떤 분포를 갖는지 볼 때 이용

 - 즉 히스토그램은 도수 분포표를 막대 그래프로 시각화 한 것

 - 주로 통계 분야에서 데이터가 어떻게 분포하는지 알아볼 때 많이 이용

import matplotlib
import matplotlib.pyplot as plt

matplotlib.rcParams['font.family'] = 'Malgun Gothic' # '맑은 고딕'으로 지정
matplotlib.rcParams['axes.unicode_minus'] = False

# * 도수 분포표 이해를 위한 용어
# 변량 variate : 자료를 측정해 숫자로 표시한 것. (예: 점수, 키, 몸무게, 판매량, 시간 등)
# 계급 class : 변량을 정해진 간격으로 나눈 구간. (예: 시험 점수를 60 ~ 70, 70 ~ 80, 80 ~ 90, 90 ~ 100 점 구간으로 나눔)
# 계급의 간격 class width : 계급을 나눈 크기. (예: 위의 시험 점수를 나눈 간격은 10)
# 도수 frequency : 나눠진 계급에 속하는 변량의 수. (예: 각 계급에서 발생한 수로 3, 5, 7, 4)
# 도수 분포표 frequency distribution table : 계급에 도수를 표시한 표.


# * 어떤 학급에서 수학 시험 결과를 이용해 도수 분포표 만드는 과정.
# 1. 변량 생성 : 학생 25명의 수학 시험 결과는 다음과 같음.
# 76, 82, 84, 83, 90, 86, 85, 92, 72, 71, 100, 87, 81, 76, 94, 78, 81, 60, 79, 69, 74, 87, 82, 68, 79

# 2. 계급 간격 설정 및 계급 생성 : 변량 중 가장 작은 숫자가 60이고 가장 큰 숫자가 100이므로
# 60에서 일정한 간격 (여기서는 5로 설정)으로 나누어서 다음과 같은 8개의 계급을 설정
# 60 ~ 65, 65 ~ 70, 70 ~ 75, 75 ~ 80, 80 ~ 85, 85 ~ 90, 90 ~ 95, 95 ~ 100

# 3. 계급별 도수 확인 및 분포표 만들기
# 각 계급에 몇 개의 변량이 들어있는지 확인해 계급별로 도수를 구함.
# 이를 이용해 계급별로 도수를 표시한 도구 분포표 만듬.
# 계급 (수학점수)         도수      마크로 도수 표시
# 60(이상) ~ 65(미만)      1        *
# 65 ~ 70                  2        **
# 70 ~ 75                  3        ***
# 75 ~ 80                  5        *****
# 80 ~ 85                  6        ******
# 85 ~ 90                  4        ****
# 90 ~ 95                  3        ***
# 95 ~ 100                 1        *

# 히스토그램은 아래와 같은 형식으로 그림.
# plt.hist(x, [, bins=bins_s 혹은 'auto'])
# x는 변량 데이터.
# 옵션 bins는 계급의 갯수로 이 개수 만큼 자동으로 계급이 생성.
# 입력하지 않으면 'auto'가 되고 기본적으로 bins=10 이 됨.
math = [76, 82, 84, 83, 90, 86, 85, 92, 72, 71, 100, 87, 81, 76, 94, 78, 81, 60, 79, 69, 74, 87, 82, 68, 79]
plt.hist(math)
plt.show()
# 도수분포표 만들 때 8개의 계급으로 나누어서 bins 옵션에 8을 입력
plt.hist(math, bins=8)
plt.show()
# 히스토그램에 x라벨, y라벨, 그래프 제목, 격자 추가
plt.hist(math, bins=8)
plt.title('수학 시험의 히스토그램')
plt.xlabel('시험 점수')
plt.ylabel('도수(frequency)')
plt.grid()
plt.show()

 

4. 한국복지패널 데이터 분석

 - 한국복지패널 데이터는 한국보건사회연구원에서 우리나라 가구의 경제활동을 연구해

 - 복지 정책에 반영할 목적으로 발간하는 조사 자료

 - 전국에서 7,000여 가구를 선정해 2006년 부터 매년 추적한 조사 자료로

 - 경제활동, 생활실태, 복지욕구 등 천여 개 변수로 구성되어 있음

 - 다양한 분야의 연구자와 정책 전문가들이 복지패널 데이터를 활용해 논문과 연구보고서를 발표하고 있음

 - 한국복지패널 데이터는 엄밀한 절차에 따라 수집되었고 다양한 변수를 담고 있으므로 데이터 분석 연습 훌륭한 재료

 - 데이터에는 다양한 삶의 모습이 담겨져 있어서 대한민국 사람들이 어떻게 살고 있는지 살펴 볼 수 있음

 

 

 - 아래 부터는 이론 내용은 기록하였지만, 코드는 놓친 부분이 있습니다.

 

 

 

# 1. '한국복지패널 데이터' 분석 준비하기

# https://www.koweps.re.kr:442/data/data/list.do

# 1) 데이터 준비하기
# Koweps_hpwc14_2019_beta2.sav : 2020년에 발간된 복지패널 데이터로 6,331가구, 14,418명의 정보를 담고 있음.

# 2) 패키지 설치 및 로드하기
# 데이터 파일은 통계 분석 소프트웨어인 SPSS 전용파일.
# pyreadstat 패키지를 설치하면 pandas 패키지의 함수를 이용해 SPSS, SAS, STATA 등 다양한 통계 분석
# 소프트웨어의 데이터 파일을 불러올 수 있음.

 

# pip install pyreadstat

import pyreadstat
import pandas as pd
import seaborn as sns
import numpy as np

# 3) 데이터 불러오기
# 데이터 원본은 복구할 상황을 대비해 그대로 두고 복사본을 만들어 분석에 활용

# raw_welfare = pd.read_spss('./input/')

# 복지패널 데이터와 같은 대규모 데이터는 변수의 수가 많고 변수명이 코드로 되어 있어
# 전체 구조를 한 눈에 파악하기 어려움
# 규모가 큰 데이터는 데이터 전체를 한 번에 파악하기보다 변수명을 쉬운 단어로 바꾼 다음
# 분석에 사용할 벼누를 하나씩 살펴봐야 함

# 5) 변수명 바꾸기
# 규모가 큰 조사 자료는 데이터의 특징을 설명해 놓은 코드북 codebook을 함께 제공
# 코드북에는 코드로 된 변수명과 값의 의미가 설명되어 있음
# 코드북을 보면 데이터의 특징이 어떠한지 감을 잡을 수 있고, 분석에 어떤 변수를 활용할지, 분석 방향의 아이디어를 얻을 수 있음
# 코드북의 파일명은 kowps_Codebook_2019.xlsx

# 코드북을 참고해 분석에 사용할 변수 7개의 이름을 알기 쉬운 단어로 바꿈.
# 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'})  # 지역 코드
# 2) 2번째 파일

# 다양한 분석 주제를 다루는데, 분석마다 2단계로 진행

# 1단계 : 변수 검토 및 전처리
# 분석에 활용할 변수를 전처리.
# 변수의 특징을 파악하고 이상치와 결측치를 정제한 다음, 변수의 값을 다루기 편하게 바꿈.
# 전처리는 분석에 활용할 변수 각각 진행.

# 2단계 : 변수 간 관계 분석
# 전처리를 완료하면 본격적으로 변수 간 관계를 파악하는 분석을 함.
# 데이터를 요약한 표와 데이터의 특징을 쉽게 이해할 수 있는 그래프를 만든 다음 분석 결과를 해석.


# 2) 성별에 따른 월급 차이 - 성별에 따라 월급이 다를까?
# 분석 절차
# 1단계 : 변수 검토 및 전처리
# 성별 / 월급
# 2단계 : 변수 간 관계 분석
# 성별 월급 평균표 만들기 / 그래프 만들기

# 1. 성별 변수 검토 및 전처리하기
# 1) 변수 검토하기

# walfare = pd.read_csv('./input/Koweps_hpc16_2021_beta2.sav')
# print(walfare.head())

# 2) 전처리하기
# 코드북을 보면 성별 변수의 값이 1이면 남자, 2면 여자를 의미. 모른다고 답하거나 응답하지 않으면 9로 입력
# 이 정보를 바탕으로 데이터에 이상치가 있는지 검토하고, 분석할 때 제거하기 편하도록 NaN 을 부여해 결측치 처리
# 즉 값이 9인 경우 성별을 알 수 없어 분석에서 제외해야 하므로 결측 처리

# 이상치 확인
# wlafare['sex'].value_counts()

# 1,2만 있고 9나 다른 값이 없으니 이상치를 결측 처리하는 절차를 건너뛰어도 됨
# 만일 이상치가 있으면 이상치를 결측 처리한 후에 다음 결측치 확인

# 이상치 결측 처리
# sex 열에서 9인 값을 NaN으로 변경
# np.where(condition, T, F)
# walfare['sex'] = np.where(welfare['sex'] == 9, np.nan, welfare['sex'])

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


# 성별이 1, 2로 되어 있어, 값의 의미를 이해하기 쉽도록 문자 male과 female로 변경
# 변경 후 잘 반영이 되었는지 value_counts()와 countplot()을 이용해 바꾼 값이 잘 반영이 됐는지 출력 결과를 확인

# 성별 항목 이름 부여
# welfare['sex'] = np.where(welfare['sex'] ==1, 'male', 'female')

# welfare['sex'].value_counts()

# 빈도 막대 그래프 만들기
# sns.countplot(data=welfare, x='sex')
# plt.show()

# 작업한 데이터프레임을 csv로 저장
# welfare.to_csv('./data/Koweps_hpwc14_2019_beta2_step_02.csv', index=False)

 

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

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# welfare = pd.read_csv('./data/Koweps_hpwc14_2019_beta2_step_02.csv')
# welfare['sex'].haed()

# 1) 변수 검토하기
# 코드북을 보면 월급은 '일한 달의 평균 임금'을 의미하여 1만원 단위로 기록
# 변수 이름은 income
# 성별은 범주 변수이므로 df.value_counts()를 이용해 범주별 빈도를 확인하면 특징을 파악할 수 있음
# 하지만 월급은 연속 변수이므로 df.value_acount()을 이용하면 너무 많은 항목이 출력되어 알아보기 어려움
# 연속 변수는 df.describe()로 요약 통계량을 확인해야 특징을 파악할 수 있음
# welfare['income'].dtype

# welfare['income'].describe() # 요약 통계량 구하기

# 출력 결과를 보면 float64 타입이고, 0 ~ 1,092만원의 값을 지님
# 150 ~ 345 만원에 가장 많이 분포하고 평균은 268만원, 중앙값은 평균보다 작은 220만원으로
# 전반적으로 낮은 쪽에 치우침 -> 월급이 평균값보다 낮은 사람이 50% 이상

# 히스토그램을 만들어 분포를 확인
# sns.hisplot(data=welfare, x='income') # 히스토그램 만들기
# plt.show()


# 2) 전처리 하기
# 코드북을 보면 월급은 만원 단위로 되어 있고, '모름/무응답'은 9999.

# welfare['income'].describe() # 이상치 확인

# welfare['income'].isne().sum() # 결측치 확인 14418

# 출력 결과를 보면 최소값은 0 ~ 1,092 이고 결측치 9,884개가 있음
# 즉 9999가 입력된 데이터는 없음
# 이상치를 결측 처리하는 절차를 건너뛰어도 됨

# 만약 9999인 항목이 있다면 아래와 같이 이상치를 결측 처리하는 절차를 거쳐야 됨
# 이상치 결측 처리



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

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# welfare = pd.read_csv('./data/Koweps_hpwc14_2019_beta2_step_02.csv')

# 1) 성별 월급 평균표 만들기

# income 결측치 제거 : dropna(subset=['income'])
# sex별 분리 : groupby('sex', as_index=False)
# income 평균 구하기 : agg(mean_income=('income', 'mean')
# sex_income = welfare.dropna(subset=['income']).groupby('sex', as_index=False).agg(mean_income=('income', 'mean'))
# sex_income = welfare.dropna(subset=['income'])
# sex_income = sex_income.groupby('sex', as_index=False)
# sex_income = sex_income.agg(mean_income=('income', 'mean'))

# 평균 남자 월급은 349만원, 여자 월급은 186만원으로, 남성이 여성보다 약 163만원이 많음

# 2) 그래프 만들기
# 분석 결과를 쉽게 이해할 수 있도록 성별 월급 평균표를 이용해 막대 그래프로 만듬

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


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

# 분석 절차
# 1단계 : 변수 검토 및 전처리
# 나이 / 월급
# 2단계 : 변수 간 관계 분석
# 나이에 따른 우러급 평균표 만들기 / 그래프 만들기

# 2) 전처리
# 코드북을 보면 태어난 연도는 '모름/무응답'일 경우 9999로 코딩
# 이 정보를 바탕으로 전처리

# welfare['birth'].describe() # 이상치 확인

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

# 이상치와 결측치가 없으므로 파생변수를 만드는 단계로 넘어감
# 만일 이상치가 발견되면 아래와 같이 전처리한 다음 분석을 진행

# 이상치 결측 처리
# welfare['birth'] = np.where(welfare['birth'] == 9999, np.nan, welfare['birth'])

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

# 3) 파생변수 만들기 - 나이
# 2019년에 조사가 진행됐으니 2019에서 태어난 연도를 뺀 다음 1을 더해 나이를 구함

# 나이 변수 만들기
# df.assign(kworgs) : DataFrame에 새 열을 할당하는 메서드. kwargs : 새열이름 = 내용 형식으로 입력되는 키워드
# 콤마(,)를 통해 여러개를 입력
# welfare = welfare.assign(age= 2019 - welfare['birth'] + 1)
#
# welfare['age'].describe()

# 히스토그램 만들기
# sns.histplot(data=welfare, x ='age')
# plt.show()
#
# welfare.to_csv('./data/Koweps_hpwc14_2019_beta2_step_03.csv', mode= w)

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

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# welfare = pd.read_csv('./data/Koweps_hpwc14_2019_beta2_step_03.csv')

# 1) 나이에 따른 월급 평균표 만들기
# 나이별 월급 평균표 만들기

# income 결측치 제거 : dropna(subset=['income'])
# age별 분리 : groupby('age')
# income 평균 구하기 : agg(mean_icome=('income', 'mean'))
# age_income = welfare.dropna(subset=['income']).groupby(['age']).agg(mean_income=('income','mean'))
# age_income.head()

# 2) 그래프 만들기
# 평균표를 이용해 그래프 작성, x축을 나이, y축을 월급으로 지정해 나이에 따른 월급의 변화를 나타낸 선 그래프 만듬

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

 


공부 과정을 정리한 것이라 내용이 부족할 수 있습니다.

부족한 내용은 추가 자료들로 보충해주시면 좋을 것 같습니다.

읽어주셔서 감사합니다 :)