멋사 AISCOOL 7기 Python/INPUT

[PANDAS] 전처리 & EDA 총정리

dundunee 2022. 10. 27. 17:37

A. 데이터 불러오기

1. 라이브러리 로드하기

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

2. 파일 불러오기

from glob import glob
file_name = glob("seoul*.csv") #seoul로 시작하는 csv 파일을 찾아달라는 의미

# 파일 변수에 담기
df = pd.read_csv(file_name, encoding="cp949")

B. 데이터 확인 및 요약하기

# 데이터 형태 보기
df.shape

# 데이터 일부만 확인하기
df.head()
df.tail()
df.sample()

# 컬럼별 타입 확인하기
df.dtypes

# 데이터 유일값 확인하기
df[columns].unique()
# 컬럼별 전체 유일값 확인
df.nunique()

C. 데이터프레임 합치기

1. CONCAT

df = pd.concat([df_01, df_02])

axis = 0 또는 axis = 1로 행으로 결합할지, 열로 결합할지 정할 수 있다

 

D. MELT로 TIDY DATA 만들기

Tidy data란 각 변수가 열이고 관측치가 행이 되도록 배열된 데이터 이다(Hadley Wickham)

#pd.melt(df, id_vars, var_name, value_name)
df_first_melt = pd.melt(df_first, id_vars="지역")

df = row.melt(id_vars=raw.columns[:4], var_name="연월", value_name="달러")

E. 결측치 확인하기

# 컬럼별 결측치 개수 확인
df.isnull().sum()

# 컬럼별 결측치 비율 확인하기
df.isnull().mean() * 100

# 결측치 heatmap 시각화
sns.heatmap(df_last.isnull().sum(), cmap="gray")

F. 기술통계값 추출하기

# 수치형 데이터의 기술통계
df.describe()

# 범주형 데이터의 기술통계
df.describe(include="object")

G. 중복값 제거하기

# 중복값 확인
df.duplicated()

# 중복값 제거
df.drop_duplicates()

H. 인덱스 설정하기

# 인덱스 재설정
df = df.set_index(column)

# 인덱스 정렬
df = df.sort_index(ascending=False)

I. 데이터 타입 변경하기

1. 날짜 데이터

df[column] = pd.to_datetime(df[columns])

2. 숫자 데이터

df[columns] = pd.to_numeric(df[columns], errors="coerce")

J. 파생변수 만들기: 시리즈 접근자(series accessor)

1. 날짜 파생변수 만들기: dt

#연도, 월, 일, 요일에 대한 파생변수 반들기
df["연도"] = df["확진일"].dt.year
df["월"] = df["확진일"].dt.month
df["일"] = df["확진일"].dt.day
df["요일"] = df["확진일"].dt.dayofweek

#파생변수끼리 합치기
df["연도월"] = df["연도"].astype('str') + "-" + df["월"].astype('str')

 

숫자로 표현되는 요일을 한글로 나타내려면?

#문자열 인덱싱을 사용
def find_dayofweek(day_no):
    dayofweek = "월화수목금토일"
    return dayofweek[day_no] #0: 월 ~ 6:일, 문자열 인덱싱으로 해결
    
df["요일명"] = df["요일"].map(find_dayofweek)
df[["요일","요일명"]].sample(5)

2. 연월 분리하기: str

'연월' 컬럼의 값이 '2022년10월"로 되어있다고 하자

# 연 분리 함수
def parse_year(date):
		return int(date.split("년")[0])
        
# 월 분리 함수
def parse_month(date):
		return date.split("년")[1]
        
# 새로운 컬럼 만들기: .appply
df_first_melt["연도"] = df_first_melt["기간"].apply(parse_year)
df_first_melt["월"] = df_first_melt["기간"].apply(parse_month)

# "월"을 지우고 데이터 타입 inr로 변경
df_first_melt["월"] = df_first_melt["월"].str.replace("월", "")
df_first_melt["월"] = df_first_melt["월"].str.replace(" ", "")
df_first_melt["월"] = df_first_melt["월"].astype(int)
df_first_melt.sample(5)

str.split(expand=True)를 사용하는 방법도 있다

df["연도"] = df_first_melt["기간"].str.split("년", expand=True)[0].astype(int)
df["월"] = df_first_melt["기간"].str.split("년", expand=True)[-1]

단순히 공백제거 및 데이터타입 변경을 통해 컬럼을 추가할 수도 있다.

# '월' 제거:  str.replace()
#양쪽 공백 제거: str.strip()
df["연"] = df["연월"].str.split(".", expand=True)[0].astype(int)
df["월"] = df["연월"].str.split(".", expand=True)[1].astype(int)
df.sample(5)

3. 정규표현식 이용

  • [ ]일치시킬 문자 세트의 패턴
  • [가나다] : 가 or 나 or 다 중에 하나를 포함하고 있는지
  • [가-힣] : 한글 가부터 힣까의 문자 중 하나를 포함하고 있는지
  • [0-9] : 0~9까지의 숫자 중 하나를 포함하고 있는지
  • [^0-9] : 숫자를 포함하고 있지 않음
  • [^가-힣] : 한글이 포함되어 있지 않음
  • [가-힣+] : 한글이 하나 이상 포함되는지

‘항목’컬럼은 ‘수출액[$]’ 혹은 ‘수입액[’$’]로 이뤄져 있어서 ‘액[$]’을 제거하고자 한다.

df["항목"].str[:2]
df["항목"].str.replace("액|[[$]]", "", regex=True)
df["항목"].str.replace("액[$]", "", regex=False)
df["항목"].str.replace("액\\[\\$\\]", "", regex=True)
df["항목"].str.replace("[^수입출]", "", regex=True)
df["항목"].str.replace("[액[|$]]", "", regex=True)
df.sample(5)

4. 딕셔너리를 이용한 파생변수 만들기

# 해당 데이터에서 사용하는 대한민국 시도코드 정보입니다.
city = """11 서울특별시
42 강원도
26 부산광역시
43 충청북도
27 대구광역시
44 충청남도
28 인천광역시
45 전라북도
29 광주광역시
46 전라남도
30 대전광역시
47 경상북도
31 울산광역시
48 경상남도
36 세종특별자치시
49 제주특별자치도
41 경기도"""


#\n 제거하기, 리스트에 담기
city_list = city.split("\n")

#딕셔너리로 코드와 시도명 반환하기
city_name = {}
for i in range(len(city_list)):
		city_name[int(city_list[i][:2])] = city_list[i][3:]
city_name

#map 메서드 사용
df['시도명'] = df["시도코드"].map(city_name)

#또는 replace를 사용할 수 있음
df['시도명'] = df["시도코드"].replace(city_name)

# df 윗부분 일부 행을 확인합니다.
df[["시도코드", "시도명"]].sample(5)

pd.read_html로 테이블태그를 읽어와 파생변수를 만든 사례

# 투여경로
path_dict = {"A":"내복제", "B":"주사제", "C":"외용제", "D":"기타"}
df["투여경로"] = df["약품일반성분명코드"].str[6].map(path_dict)

# 제형
df['제형코드'] = df["약품일반성분명코드"].str[7:]

table = pd.read_html('https://www.health.kr/drug_info/basedrug/main_ingredient.html')
table[1]

drug_table = table[1][["제형코드","제형명칭"]]

#방법1. 데이터프레임을 딕셔너리로 가져오기
#딕셔너리 생성
drug_list = {}
#데이터프레임 딕셔너리로 가져오기
drug_list = drug_table.set_index("제형코드")["제형명칭"].to_dict()
#map으로 넣기
df['제형명칭'] = df["제형코드"].map(drug_list)

#방법2. merge로 합치기
df = df.merge(drug_table, on="제형코드", how="left")

5. str.contains 사용하기

  • 해외유입과 국내유입 구분하기
df.loc[df["접촉력"].str.contains("해외유입"), "해외유입"]="해외"
df.loc[~df["접촉력"].str.contains("해외유입"), "해외유입"]="국내"

K. 컬럼값 변경하기

#규모구분 column에서 '전용면적, 제곱미터이하, 제곱미터초과', 띄어쓰기를 대체 
df_last["전용면적"] = df_last["규모구분"].str.replace("전용면적|제곱미터이하", "")
df_last["전용면적"] = df_last["규모구분"].str.replace("제곱미터초과", "~")
df_last["전용면적"] = df_last["규모구분"].str.replace(" ", "")

L. 필요없는 컬럼 제거

df_last = df_last.drop(columns=["규모구분", "분양가격"])
df_last = df_last.drop(labels=["규모구분", "분양가격"], axis=1)

M. 컬럼명 변경하기

df = df.rename(columns={"국가및권역별": "국가권역", "전산업·소재부품장비산업별":"산업"})