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

 

🐬  분석은 2단계로 진행

< 1단계 : 변수 검토 및 전처리 >

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

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

 

1) 데이터 준비하기

 

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


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


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

pip install pyreadstat

 

3) 데이터 불러오기

 

👾  데이터 원본은 복구할 상황을 대비해 그대로 두고 복사본을 만들어 분석에 활용

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

raw_welfare = pd.read_spss('../input/Koweps_hpwc14_2019_beta2.sav')

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

 

4) 데이터 검토


👾  데이터의 구조와 특징을 파악

# 앞부분, 뒷부분 출력
welfare.head()  

# 행, 열 개수 출력
welfare.shape  # (14418, 830)

# 변수 속성 출력
welfare.info()  
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 14418 entries, 0 to 14417
Columns: 830 entries, h14_id to h14_pers_income5
dtypes: float64(826), object(4)
memory usage: 91.3+ MB
'''

# 요약 통계량
welfare.describe()



5) 변수명 바꾸기

 

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

   ⚡️  규모가 큰 조사 자료는 데이터의 특징을 설명해 놓은 코드북 codebook을 함께 제공
   ⚡️  코드북에는 코드로 된 변수명과 값의 의미가 설명되어 있음
   ⚡️  코드북을 보면 데이터의 특징이 어떠한지 감을 잡을 수 있고, 분석에 어떤 변수를 활용할지, 분석 방향의 아이디어를 얻을 수 있음
   ⚡️  코드북의 파일명은 Koweps_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'})  # 지역 코드
welfare.columns
'''
Index(['h14_id', 'h14_ind', 'h14_sn', 'h14_merkey', 'h_new', 'h14_cobf',
       'p14_wsc', 'p14_wsl', 'p14_wgc', 'p14_wgl',
       ...
       'wc14_64', 'wc14_65', 'wc14_5aq4', 'wc14_5aq5', 'wc14_5aq6',
       'h14_pers_income1', 'h14_pers_income2', 'h14_pers_income3',
       'h14_pers_income4', 'h14_pers_income5'],
      dtype='object', length=830)
'''

 

6) 복사본 저장

welfare.to_csv('../output/Koweps_hpwc14_2019_beta2_step_01.csv', mode='w', index=False)

 

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

< 분석 절차 >

    ·  1단계 : 변수 검토 및 전처리
                    성별 / 월급
    ·  2단계 : 변수 간 관계 분석
                     성별 월급 평균표 만들기 / 그래프 만들기

 

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

a. 변수 검토하기

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

welfare = pd.read_csv ('../output/Koweps_hpwc14_2019_beta2_step_01.csv')
welfare.head()

# sex 성별 변수의 타입을 파악
welfare['sex'].dtypes # dtype('float64')

# value_counts()를 이용해 각 범주마다 몇 명이 있는지 알아봄
welfare['sex'].value_counts() 
'''
sex
2.0    7913
1.0    6505
Name: count, dtype: int64
'''

 


 

b.  전처리하기


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

 

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

 

# 이상치 결측 처리
# sex 열에서 9인 값을 NaN으로 변경
welfare['sex'] = np.where(welfare['sex'] == 9, np.nan, welfare['sex'])
-> '9'인 값이 존재하면 np.nan 값이 들어가게 되고, 아니면 원래 값이 들어가게 됨

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

 

  💡  np.where(condition, T, F) : 조건에 해당하는 값이면 'T', 해당하지 않는 값이면 'F' 가 기입되게 된다.

 

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

# 성별 항목 이름 부여
welfare['sex'] = np.where(welfare['sex'] == 1, 'male', 'female')
#-> 1이면 male, 아니면 female 기입되게 된다.

welfare['sex'].value_counts()
'''
sex
female    7913
male      6505
Name: count, dtype: int64
'''

 

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

출력 결과

 


 

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

 

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

welfare = pd.read_csv('../output/Koweps_hpwc14_2019_beta2_step_02.csv')
welfare['sex'].head()
'''
0    female
1      male
2      male
3      male
4    female
Name: sex, dtype: object
'''

 


 

1) 변수 검토하기 

 

📍  코드북을 보면 월급은 '일한 달의 평균 임금'을 의미하며 1만원 단위로 기록
         ▶️  변수 이름은 income
📍  성별은 범주 변수이므로 df.value_counts()를 이용해 범주별 빈도를 확인하면 특징을 파악할 수 있음
📍  월급은 연속 변수이므로 df.value_acount()을 이용하면 너무 많은 항목이 출력되어 알아보기 어려움

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
'''

 

  ✏️  출력 결과를 보면 float64 타입이고, 0~1892만원의 값을 지님
  ✏️  150~345 만원에 가장 많이 분포하고 평균은 268만원, 중앙값은 평균보다 작은 220만원으로 전반적으로 낮은 쪽에 치우침  

          ➡️  월급이 평균값보다 낮은 사람이 50% 이상

 

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

 


 

2)  전처리 하기

 

📍  코드북을 보면 월급은 만원 단위로 되어 있고, '모름/무응답'은 9999

welfare['income'].describe()  # 이상치 확인
welfare['income'].isna().sum()  # # 결측치 확인 14418 - 4534 = 9884
# 9884

 

  ✏️   출력 결과를 보면 최소값은 0 ~ 1,892이고 결측치 9,884개가 있음
           ▶️ 즉 9999가 입력된 데이터는 없음

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

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

 


 

4. 성별에 따른 월급 차이 분석

 

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

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

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

welfare = pd.read_csv('../output/Koweps_hpwc14_2019_beta2_step_02.csv')

sex_income = welfare.dropna(subset=['income'])
sex_income = sex_income.groupby('sex', as_index=False)
sex_income = sex_income.agg(mean_income=('income', 'mean'))

sex_income

'''
      sex  mean_income
0  female   186.293096
1    male   349.037571
'''

 

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


 

2) 그래프 만들기


📍  분석 결과를 쉽게 이해할 수 있도록 성별 월급 평균표를 이용해 막대 그래프로 만듦

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

 


 

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

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

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

welfare = pd.read_csv('../output/Koweps_hpwc14_2019_beta2_step_02.csv')
welfare['birth'].head()
'''
0    1945.0
1    1948.0
2    1942.0
3    1962.0
4    1963.0
Name: birth, dtype: float64
'''

 

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

 

a. 변수 검토하기

 

  📍  나이 변수는 없고 태어난 연도 변수만 있음. 따라서 태어난 연도 변수를 기반으로 나이 변수를 만들어야 함

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')  # 히스토그램 만들기
plt.show()


 

b.  전처리

 

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

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

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

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

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

 

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

 

📍  2019년에 조사가 진행됐으니 2019에서 태어난 연도를 뺀 다음 1을 더해 나이를 구함

📍  df.assign(kwargs) : DataFrame에 새 열을 할당하는 메서드. 

                                               kwargs : 새열이름 = 내용 형식으로 입력되는 키워드. 콤마(,)를 통해 여러개를 입력.

# 나이 변수 만들기
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')

 

# 변경된 자료 저장
welfare.to_csv('../output/Koweps_hpwc14_2019_beta2_step_03.csv', mode='w', index=False)

 


 

6. 나이와 월급의 관계 분석

 

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


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

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

welfare = pd.read_csv('../output/Koweps_hpwc14_2019_beta2_step_03.csv')

age_income = welfare.dropna(subset=['income']).groupby('age').agg(mean_income=('income', 'mean'))
age_income.head()

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

 


 

2)  그래프 만들기

 

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

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

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

 


 

1.  Folium 라이브러리

 


 

2. 지도 만들기

🚀  folium 라이브러리의 Map() 함수를 이용하여 지도 객체를 생성
🚀  지도 화면은 고정된 것이 아니고 줌 Zoom 기능과 화면 이동 Scroll이 가능

    ⚡️  folium은 웹 기반 지도를 만들기 때문에  웹 환경에서만 지도를 확인할 수 있음
    ⚡️  지도를 보려면 지도 객체에 save() 메서드를 적용하여 HTML 파일로 저장하고 웹 브라우저에서 파일을 열어서 확인
            ➡️  주피터 노트북에서는 바로 지도 객체를 확인할 수 있음

import folium

# 서울 지도 만들기
# location 옵션에 [위도, 경도] 수치를 입력하면 그 지점을 중심으로 지도를 보여줌
# zoom_start 옵션을 사용하면 화면 확대 비율을 조절할 수 있음
seoul_map = folium.Map(location=[37.55, 126.98], zoom_start=12)
seoul_map

# 지도를 HTML 파일로 저장하기
seoul_map.save('../output/seoul.html')

 


 

3. 지도 스타일 적용하기

🚀  Map() 함수에 tiles 옵션을 적용하면 지도에 적용하는 스타일을 변경하여 지정할 수 있다

🚀  tiles 스타일 종류

    → tiles = 'OpenStreetMap' (기본값)
    → tiles = 'Cartodb Positron' or 'cartodbpositron' (단계 구분도가 잘 표현 되도록 밝은 색으로 바꿈)

    → tiles = 'Cartodb dark_matter' (지도 색상을 다크모드로 지정)

import folium

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

 


 

4. 지도 마커 (Marker) 표시하기

 

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

import pandas as pd
import folium

# 대학교 리스트를 데이터프레임 변환
df = pd.read_excel('../input/서울지역 대학교 위치.xlsx')
'''
           name         위도          경도
0  KAIST 서울캠퍼스   37.592573  127.046737
1         KC대학교  37.548345  126.854797
2  가톨릭대학교(성신교정)  37.585922  127.004328
3  가톨릭대학교(성의교정)  37.499623  127.006065
4      감리교신학대학교  37.567645  126.961610
'''

# 서울 지도 만들기
seoul_map = 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_map

 

⚡️ folium.Marker() 함수의 인수

  • [위도, 경도] 는 마커를 찍을 좌표
  • popup = '클릭문구' 는 마우스 클릭시 표시되는 문구
  • tooltip = '오버문구' 는 마우스를 갖다 놓으면 표시되는 문구
  • icon = folium.Icon(color='red', icon='star') 은 아이콘의 색상과 모양을 설정
  • add_to(m) 은 설정한 모든 내용을 현재 지도에 적용하라는 의미

출력 결과


# 지도를 HTML 파일로 저장하기
seoul_map.save('../output/seoul_colleges.html')

 


💡 대학교 위치정보를 CircleMarker()로 표시
      -  Marker() 대신 CircleMarker()를 사용. 원형 마커의 크기, 색상, 투명도 들을 설정할 수 있음

for name, lat, lng in zip(df['name'], df['위도'], df['경도']):
    folium.CircleMarker([lat, lng], popup=name,
                        radius=10,     # 원의 반지름
                        color='brown', # 원의 둘레 색상
                        fill=True,
                        fill_color='coral', # 원을 채우는 색
                        fill_opacity=0.7  # 투명도
                        ).add_to(seoul_map)
seoul_map

출력 결과

 


 

5.  단계 구분도 Choropleth Map 표시

🚀  행정구역과 같이 지도 상의 어떤 경계에 둘러싸인 영역에 색을 칠하거나 음영 등으로 정보를 나타내는 시각화 방법

🚀  전달하는 정보의 값이 커지면 영역에 칠해진 색이나 음영이 진해짐

 

import json
import pandas as pd
import folium

# 경기도 인구변화 데이터를 불러와서 데이터프레임으로 변환
# 경기도 지역의 시군구별 인구변화 데이터 (2007 ~ 2017)
df = pd.read_excel('../input/경기도인구데이터.xlsx', index_col='구분')
df.head()
'''
          2007    2008    2009    2010    2011    2012    2013    2014  \
구분                                                                       
수원시장안구  287474  285803  290798  293692  290999  291757  300908  301196   
수원시권선구  310553  308177  304097  306783  321176  332633  331773  339835   
수원시팔달구  216945  213235  219833  216503  209772  206794  204805  203479   
수원시영통구  252730  260210  258421  260557  266542  289074  310671  329718   
성남시수정구  256744  248452  242161  241070  236123  233997  228167  223539   

          2015    2016    2017  
구분                              
수원시장안구  299016  296479  293828  
수원시권선구  351053  358393  365653  
수원시팔달구  199180  198515  193311  
수원시영통구  335375  340654  349836  
성남시수정구  219531  232841  236932  
'''

df.info()
'''
<class 'pandas.core.frame.DataFrame'>
Index: 44 entries, 수원시장안구 to 양평군
Data columns (total 11 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   2007    44 non-null     int64
 1   2008    44 non-null     int64
 2   2009    44 non-null     int64
 3   2010    44 non-null     int64
 4   2011    44 non-null     int64
 5   2012    44 non-null     int64
 6   2013    44 non-null     int64
 7   2014    44 non-null     int64
 8   2015    44 non-null     int64
 9   2016    44 non-null     int64
 10  2017    44 non-null     int64
dtypes: int64(11)
memory usage: 4.1+ KB
'''

# int -> str 타입 변경
df.columns = df.columns.map(str)

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

geo_path = '../input/경기도행정구역경계.json'
geo_data = json.load(open(geo_path))
geo_data
'''
{'type': 'FeatureCollection',
 'features': [{'type': 'Feature',
   'properties': {'code': 31380,
    'name': '양평군',
    'name_eng': 'Yangpyeong-gun',
    'base_year': 2013},
   'geometry': {'type': 'Polygon',
    'coordinates': [[[127.56113535909492, 37.6256560539258],
 '''생략'''
 '''

# 경기도 지도 만들기
g_map = folium.Map(location=[37.5502, 126.982], zoom_start=9)
g_map

출력 결과


# 출력할 연도 선택 (2007 ~ 2017년 중에서 선택)
year = '2017'

# Choropleth 클래스로 단계구분도 표시하기
folium.Choropleth(geo_data=geo_path,  # 지도 경계
                  data=df[year],  # 표시하려는 데이터
                  columns=[df.index, df[year]],  # 열 지정
                  fill_color='YlOrRd', fill_opacity=0.7, line_opacity=0.5,
                  threshold_scale=[10000, 100000, 300000, 500000, 700000],
                  # -> 임계값 수치, 10000명/100000명...
                  key_on='feature.properties.name'
                  ).add_to(g_map)
g_map

  📌  geo_data : Choropleth 맵에 사용될 지리 정보

  📌  key_on : geo_data 내용에서 지리 영역을 구분할 열 이름 호출 ( ex. '양평군', '이천시'...)

  📌  data : 추출한 DataFrame에서 Choropleth 맵에 사용될 데이터 

  📌  columns : 추출한 DataFrame에서 데이터로 사용될 열 이름

 

출력 결과

 

 

 

 

 

[ 내용 참고: IT 학원 강의 ]


 

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

🐰  선 그래프 line chart : 데이터를 선으로 표현한 그래프, 시간에 따라 달라지는 데이터를 표현할 때 자주 사용
🐰  환율, 주가지수 등 경제 지표가 시간에 따라 변하는 양상을 '선 그래프'로 표현

    🥕  시계열 데이터 time series data  : 일별 환율처럼, 일정 시간 간격을 두고 나열된 데이터
    🥕  시계열 그래프 time series chart : 시계열 데이터를 선으로 표현한 그래프

 


 

1) 시계열 그래프 만들기

 

🐰  economics는 미국의 여러 가지 경제 지표를 월별로 나타낸 데이터
🐰  economics를 이용해 시간에 따라 실업자 수가 어떻게 변하는지 나타낸 시계열 그래프를 생성

🐰  sns.lineplot()을 이용하면 선 그래프를 만들 수 있다

 

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

# economics 데이터(시계열 데이터) 불러오기
economics = pd.read_csv('../input/economics.csv')

'''
         date    pce       pop  psavert  uempmed  unemploy
0  1967-07-01  506.7  198712.0     12.6      4.5      2944
1  1967-08-01  509.8  198911.0     12.6      4.7      2945
2  1967-09-01  515.6  199113.0     11.9      4.6      2958
3  1967-10-01  512.2  199311.0     12.9      4.9      3143
4  1967-11-01  517.4  199498.0     12.8      4.7      3066
'''
# x축에는 시간을 나타낸 date, y축에는 실업자 수를 나타낸 uneploy를 지정
sns.lineplot(data=economics, x='date', y='unemploy')
plt.show()

 

 

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

 

 

 

 

 

 


 

(1)  x축에 연도 표시하기

 

🥕  x축에 연도를 표시하려면 변수 타입을 날짜 시간 타입 datetime64으로 바꿔야
       ( economics 데이터의 date가 문자 object 타입으로 되어 있음 )

🥕  pd.to_datetime()을 이용하면 변수의 타입을 날짜 시간 타입으로 바꿀 수 있음

        ⚡️  변수의 타입을 날짜 시간 타입으로 바꾸더라도 값이 달라지지 않음

🥕  날짜 시간 타입은 df.dt를 이용해 연, 월, 일을 추출할 수 있음

# 날짜 시간 타입 변수 만들기
# date 타입을 날짜 시간 타입으로 변경해서 date2 변수 추가
economics['date2'] = pd.to_datetime(economics['date'])

# 변수 타입 확인
economics.info()
'''
RangeIndex: 574 entries, 0 to 573
Data columns (total 7 columns):
 #   Column    Non-Null Count  Dtype         
---  ------    --------------  -----         
 0   date      574 non-null    object        
... 생략...    
 6   date2     574 non-null    datetime64[ns]
 '''
# 연도 변수 추가
economics['year'] = economics['date2'].dt.year
economics.head()
# 연도를 나타낸 변수를 sns.lineplot()의 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()

신뢰구간 제거 결과

 

# date2로 그래프 바로 생성
sns.lineplot(data=economics, x='date2', y='unemploy')
plt.show()

 

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1. 상자 수염 그래프  Box plot

 

🍒  데이터의 분포 또는 퍼져 있는 형태를 직사각형 상자 모양으로 표현한 그래프
🍒  상자 그림을 보면 데이터가 어떻게 분포하고 있는지 알 수 있기 때문에 평균값만 볼 때 보다 데이터의 특징을 더 자세히 이해할 수 있음

🍒  사람의 나이가 500살, 키가 5미터 등은 표현은 가능하지만 현실적으로 불가능한 값들 이를 이상치, 극단치라고 하는데

      이상치는 효과적인 데이터 분석을 위해 제거해야 함
       ⚡️  이상치를 제거하기 위해 값의 정상 범위를 정하는 방법이 있다.

              ▶️  나이의 경우 121살은 이상치로 보는 것
       ⚡️  다른 방법으로 통계적인 기법을 사용
              ▶️  정규 분포에서 상하위 0.2% 밖의 데이터를 극단적인 값으로 가정하여 제거


 

1) 상자 그림 만들기

 

✏️  sns.boxplot()을 사용하여 그래프 생성

✏️  값을 크기순으로 나열해 4등분했을 때 위치하는 값인 '사분위수'를 이용해 그래프가 생성 된다
✏️  다음은 상자 그림의 요소가 나타내는 값

상자 그림 설명
상자 아래 세로선   아랫수염 하위 0 ~ 25% 내에 해당하는 값
상자 밑면  1사분위수(Q1) 하위 25% 위치 값
상자 내 굵은 선 2사분위수(Q2) 하위 50% 위치 값 (중앙값)
상자 윗면  3사분위수(Q3) 하위 75% 위치 값
상자 위 세로선 윗수염 하위 75 ~ 100% 내에 해당하는 값
상자 밖 가로선  극단치 경계 Q1, Q3 밖 1.5 IQR 내 최대값
상자 밖 점 표식 극단치  Q1, Q3 밖 1.5 IQR을 벗어난 값

  📍  IQR(사분위 범위)은 1사분위수와 3사분위수의 거리(직사각형의 높이)를 뜻하고 '1.5 IQR'은 IQR의 1.5배을 뜻함


 

📁  mpg 데이터를 이용해 x축을 drv, y축을 hwy로 지정하고 '구동 방식별 고속도로 연비'를 상자 그림으로 표현

     📌  mpt.csv : '구동 방식별 고속도로 연비 평균'
     📌  displ(배기량)
     📌  hwy(고속도로 연비)
     📌  drv(구동방식)

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

# 데이터 준비
mpg = pd.read_csv('../input/mpg.csv')

# 그래프 생성
sns.boxplot(data=mpg, x='drv', y='hwy')
plt.show()

 

 

📍  전륜구동(f)은 26 ~ 29 사이의 좁은 범위에 자동차가 모여 있는 뾰족한 형태의 분포
📍  수염의 위아래에 점 표식이 있는 것을 보면 연비가 극단적으로 높거나 낮은 자동차들이 존재
📍  4륜구동(4)은 17 ~ 22 사이에 자동차 대부분이 모여 있는 형태
        ▶️ 중앙값이 상자 밑면에 가까운 것을 보면 낮은 값 쪽으로 치우친 형태의 분포
📍  후륜구동(r)은 17 ~ 24 사이의 넓은 범위에 자동차가 분포
        ▶️ 수염이 짧고 극단치가 없는 것을 보면 자동차 대부분이 사분위 범위에 해당

 

 

 

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1.  산점도

🌻  데이터를 x축과 y축에 점으로 표현한 그래프
🌻  나이와 소득처럼 연속값으로 된 두 변수의 관계를 표현할 때 사용

 

1) 데이터 준비

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

mpg = pd.read_csv('../input/mpg.csv')
mpg.head()
'''
  manufacturer model  displ  year  cyl       trans drv  cty  hwy fl category
0         audi    a4    1.8  1999    4    auto(l5)   f   18   29  p  compact
1         audi    a4    1.8  1999    4  manual(m5)   f   21   29  p  compact
2         audi    a4    2.0  2008    4  manual(m6)   f   20   31  p  compact
3         audi    a4    2.0  2008    4    auto(av)   f   21   30  p  compact
4         audi    a4    2.8  1999    6    auto(l5)   f   16   26  p  compact
'''

 

📍 mpg.csv : '구동 방식별 고속도로 연비 평균'
📍 displ(배기량)
📍 hwy(고속도로 연비)
📍 drv(구동방식)


 

2) 그래프 생성

 

🌻  sns.scatterplot() : 산점도 만들때 사용
🌻  data : 그래프를 그리는 데 사용할 데이터 프레임을 입력
🌻  x, y : x축과 y축에 사용할 변수(데이터 프레임의 열)를  문자 형태로 입력

# x축은 displ, y축은 hwy를 나타낸 산점도 만들기
# mpg 데이터의 displ(배기량) 변수를 x축에, hwy(고속도로 연비) 변수를 y축에 놓음
sns.scatterplot(data=mpg, x='displ', y='hwy')
plt.show()

출력 결과


 

2. 추가 속성 적용

1) 축 범위 설정

 

🌻  축은 기본적으로 최소값에서 최대값까지 모든 범위의 데이터를 표현하도록 설정

🌻  데이터 전체가 아니라 일부만 표현하고 싶을 때는 축 범위를 설정
       ⚡️  sns.set() : 범위를 설정하는데 사용
       ⚡️  xlim, ylim을 이용해 설정

# xlim을 이용해 x축 범위 3~6으로 제한
sns.scatterplot(data=mpg, x='displ', y='hwy').set(xlim=(3, 6))
plt.show()

출력 결과


 

2) 종류별 표식 색깔 변경

 

🌻  hue='변수명'를 이용하면 표식 marker의 색깔을 종류별로 다르게 표현할 수 있음

# drv별로 표식 색깔 다르게 표현
sns.scatterplot(data=mpg, x='displ', y='hwy', hue='drv')
plt.show()

출력 결과


 

3) 그래프 활용

 

📌  Runtime Configuration Parameters = rcParams

       ▶️ 그래프 설정 변경할 때 사용

# 그래프 설정 바꾸기
plt.rcParams.update({'figure.dpi': '150'})  # 해상도, 기본값 72
plt.rcParams.update({'figure.figsize': [8,6]})  # 그림 크기, 기본값 [6,4]
plt.rcParams.update({'font.size': '15'})  # 글자 크기, 기본값 10
plt.rcParams.update({'font.family': 'AppleGothic'})  # 폰트, 기본값 sans-serif

# 여러 요소를 한 번에 설정하려면 {}에 설정값을 나열
plt.rcParams.update({'figure.dpi': '150',
                     'figure.figsize': [8,6],
                     'font.size': '15',
                     'font.family': 'AppleGothic'})

# 모든 설정 되돌리기
# 같은 페이지내에서 변경된 설정을 되돌림
# plt.rcParams.update(plt.rcParamsDefault)

sns.scatterplot(data=mpg, x='displ', y='hwy')
plt.show()

출력 결과

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1.  시본 산점도 그래프

🍓  시본 산점도 그래프는 스트립 플롯 Strip Plot 그래프, 스웜 플롯 Swarm Plot 그래프 등이 있음
🍓  맷플롯립의 산점도 그래프처럼 모든 데이터를 점으로 표현하는데,
      맷플롯립의 산점도보다 범주에 따른 각 분포의 실제 데이터나 전체 형상등을 보여 준다는 장점이 있음

 

1) 데이터 준비

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

data6 = pd.read_pickle('../output/data6.pickle')

# data6에서 남성 및 여성이 성별, 몸무게, 허리둘레, 음주 여부, 흡연 상태 데이터를 가져와
# male_data, female_data에 각각 저장
male_data = data6.loc[data6.gender == 'Male', 
                     ['gender', 'weight', 'waist', 'drinking', 'smoking']]
female_data = data6.loc[data6.gender == 'Female', 
                       ['gender', 'weight', 'waist', 'drinking', 'smoking']]
male_data.head()

'''
  gender  weight  waist      drinking      smoking
0   Male      60   72.1  Non-drinking  Non-smoking
3   Male      70   90.8  Non-drinking  Non-smoking
5   Male      85   94.0      Drinking      Smoking
6   Male      80   93.0      Drinking      Smoking
7   Male      65   92.0  Non-drinking      Smoking
'''

 


 

2) 시본 스트립 플롯 생성

 

🍬  stripplot() : 데이터 개수가 1개이고 변수의 종류가 연속적이거나 범주형인 데이터에 대해 간단히 요약하여 띠 형태로 보여준다
        ▶️ 상자수염 또는 바이올린 그래프를 보충하는 그래프로 많이 사용
🍬  일반적으로 작은 데이터를 다루는 용도로 사용되는데, 큰 데이터를 다룰 때는 주로 히스토그램 등을 많이 사용

plt.figure(figsize=(10, 5))  # 그래프의 크기를 지정
plt.title('Seaborn Strip Plot Graph')  # 그래프의 제목을 지정

# stripplot() 함수로 허리 둘레 데이터를 x축에 지정, 몸무게 데이터를 y축에 각각 지정
sns.stripplot(data=male_data, x='waist', y='weight')
sns.stripplot(data=female_data, x='waist', y='weight')

# 허리둘레 최솟값, 최댓값
min(female_data['waist'])  # 53
max(male_data['waist'])  # 128

# x축 눈금 간격(눈금 개수는 총 127개)을 허리둘레의 최솟값(53)과 최댓값(128)을 중심으로 지정
plt.xticks(np.arange(0, 127, 63), labels=[53, 90.5, 128])
plt.show()

출력 결과


 

3) 팔레트 속성으로 색상 지정

 

🍬  시본의 색상 표현
    - 시본 사이트  https://seaborn.pydata.org/tutorial/color_palettes.html#palette-tutorial
    - 그래프 색상을 사용하는 원칙과 6개의 기본 팔레트 외에도 다양한 색상 팔레트를 확인할 수 있음

 

Choosing color palettes — seaborn 0.13.2 documentation

Choosing color palettes Seaborn makes it easy to use colors that are well-suited to the characteristics of your data and your visualization goals. This chapter discusses both the general principles that should guide your choices and the tools in seaborn th

seaborn.pydata.org

 

plt.figure(figsize=(10, 5))  # 그래프의 크기를 지정
plt.title('Seaborn Strip Plot Graph - Color Palette')  # 그래프의 제목을 지정

# stripplot() 함수로 허리 둘레 데이터를 x축에 지정, 몸무게 데이터를 y축에,
# 성별을 hue 속성에 지정, 팔레트 종류 dark, Set1을 palette 속성에 각각 지정.
sns.stripplot(data=male_data, x='waist', y='weight', hue='gender', palette='dark')
sns.stripplot(data=female_data, x='waist', y='weight', hue='gender', palette='Set1')

plt.xticks(np.arange(0, 127, 63), labels=[53, 90.5, 128])
plt.show()

출력 결과

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts