TIL_87. Cleaning Data in Python (1)

소고기는레어·2021년 3월 30일
0

TIL 📝

목록 보기
89/96
post-thumbnail

2021. 03. 22 월요일

Cleaning Data in Python

Common data problems

판다스의 데이터 프레임을 통해 데이터의 전처리에 대해 알아보았다.

데이터 파악, 타입 변환, 문자열 처리

  • .info() 를 통해 데이터 프레임 등 객체의 정보를 불러올 수 있다.

    • 데이터프레임.info()
  • .describe() 를 통해 열의 요약 통계(집계, 평균, 중앙값, 표준편차, 최소값, 최대값, 백분율(25%, 50%, 75%), 최대값) 를 불러올 수 있다.

    • 데이터프레임['열 이름'].describe()
  • .astype() 를 통해 열의 데이터 유형을 변환할 수 있다.

    • 데이터프레임['열 이름'] = 데이터프레임['열 이름'].astype('데이터타입')
  • assert 는 뒤의 조건이 True가 아닐 경우 에러를 반환한다. 이를 통해 확인하고자 하는 내용을 체크할 수 있다.

    • assert 데이터프레임['열 이름'].dtype == '데이터타입'
  • .strip() 를 통해 선행과 후행 문자가 제거할 수 있다.

    • a = '00012345000'; print(a.strip('0')) -> 12345

정상 범위를 벗어난 데이터

  • 데이터에 대한 파악이 끝났다면 해당 데이터의 정상 범위를 이해하고 해당 데이터에서 나올 수 없는 비정상적인 데이터를 구분할 수 있게된다.

  • 날짜를 예로 들자면, 현재를 포함한 과거의 날짜가 정상 범위인 데이터에서 미래의 날짜가 발견된다면 비정상적인 데이터로 볼 수 있다.
    이러한 경우에는 오늘과 비교하여 더 미래인 날짜를 찾아서 오늘 날짜로 수정하는 등의 처리를 거칠 수 있다.

import datetime as dt
import pandas as pd

#'date'를 datetime으로 변환하여 'date_convert'에 저장
데이터프레임['date_convert'] = pd.to_datetime(데이터프레임['date'])

#오늘 날짜를 'today'에 저장
today = dt.date.today()

#오늘보다 미래인 날짜를 전부 오늘 날짜로 수정
데이터프레임.loc['date_convert' > today, 'date_convert'] = today

#수정이 제대로 적용되었는지 확인을 위해 가장 최근의 날짜 불러오기
print(데이터프레임['date_conver'].max())

중복값

  • .duplicated() 를 통해 중복값을 찾아낼 수 있다.
    • subset 을 통해 중복 데이터를 탐색할 열을 정한다.
    • keep 을 통해 중복 데이터를 어떻게 처리할지 결정한다.
      • keep = 'first' : 중복될 경우 첫 데이터를 제외하고 나머지를 마크 혹은 삭제한다.
      • keep = 'last' : 중복될 경우 마지막 데이터를 제외하고 나머지를 마크 혹은 삭제한다.
      • keep = False : 모든 중복 데이터를 마크 혹은 삭제한다.
import pandas as pd

#'열이름' 이 중복되는 데이터를 탐색한다.
중복값 = 데이터프레임.duplicated(subset = '열 이름', keep = False)

#위에서 탐색한 중복 데이터들을 따로 분리 후 '열 이름' 으로 정렬한다.
중복데이터 = 데이터프레임[중복값].sort_values('열 이름')

#해당 데이터들을 전부 불러와서 비교한다.
print(중복데이터[['열 이름', '열 이름2', '열 이름3']])
  • 중복값 처리(이해 필요)
# 중복 데이터를 drop한다.
ride_dup = ride_sharing.drop_duplicates()

# 집계함수를 위한 통계 dictionary를 만든다.
statistics = {'user_birth_year': 'min', 'duration': 'mean'}

# ride_id로 Group by하여 통계를 계산한다.
ride_unique = ride_dup.groupby('ride_id').agg(statistics).reset_index()

# 중복 데이터가 있는지 다시 확인한다.
duplicates = ride_unique.duplicated(subset = 'ride_id', keep = False)
duplicated_rides = ride_unique[duplicates == True]

# assert를 활용하여 점검한다.
assert duplicated_rides.shape[0] == 0

Text and categorical data problems

  • .unique() 를 통해 특정 Column의 유니크값을 구할 수 있다.
    데이터프레임['column명'].unique()
  • set() 으로 집합 자료형을 생성할 수 있다. 집합 자료형은 중복을 허용하지 않고, 순서가 없는 자료형이다.
  • .difference() 로 차집합을 구할 수 있다.

1-1. 차집합을 통해 비정상 데이터 찾기

# df의 column에 포함될 수 있는 정상 데이터를 df_2 의 column_2에 저장해놨을 때,
# df의 column 과 df_2의 column_2 의 차집합을 구하여 df에 포함된 비정상 데이터 찾기
df_diff = set(df['column']).difference(df_2['column_2'])

# 위에서 찾은 비정상 데이터를 포함하고 있는 row의 인덱스 번호 구하기
df_diff_row = df['column'].isin(df_diff)

# 위에서 구한 인덱스 번호를 통해 해당 데이터 불러오기
print(df[df_diff_row])

1-2. 위의 코드블록을 활용하여 정상 데이터만 출력

# df의 column에 포함될 수 있는 정상 데이터를 df_2 의 column_2에 저장해놨을 때,
# df의 column 과 df_2의 column_2 의 차집합을 구하여 df에 포함된 비정상 데이터 찾기
df_diff = set(df['column']).difference(df_2['column_2'])

# 위에서 찾은 비정상 데이터를 포함하고 있는 row의 인덱스 번호 구하기
df_diff_row = df['column'].isin(df_diff)

# 위에서 구한 인덱스 번호를 통해 해당 데이터 불러오기(비정상 데이터)
print(df[df_diff_row])

# 해당 데이터를 제외한 데이터 불러오기(정상 데이터)
print(df[~df_diff_row])
  1. 카테고리 통일하기
  • 같은 카테고리지만 대/소문자 혹은 공백으로 구분되어 있는 경우 보통 전처리 과정에서 통합하게 된다.
# Print unique values of both columns
print(df['column'].unique())
print(df['column1'].unique())

# 대문자를 전부 소문자로 변경하여 통일시키고, 같은 의미의 카테고리의 경우 이름을 하나로 통일한다.
df['column'] = df['column'].str.lower() 
df['column'] = df['column'].replace({'사과':'apple'})

# 공백으로 구분되는 카테고리를 통합하기 위해 공백을 제거한다.
df['column1'] = df['column1'].str.strip(' ')

# 결과를 확인하기 위해 각 column의 유니크값을 불러온다.
print(df['column'].unique())
print(df['column1'].unique())
  1. 카테고리 리매핑
    -.cut()을 활용하여 데이터 값을 분할하고 정렬할 수 있다.
# 생성할 카테고리의 범위와 카테고리명을 생성한다.
label_ranges = [0, 60, 180, np.inf]
label_names = ['short', 'medium', 'long']

# 기존의 column과 위에서 생성한 것을 바탕으로 카테고리를 생성한다.
# cut()을 활용하여 기존의 column을 label_ranges에 맞춰 분리하고 label_names에 저장한다.
df['new_cat'] = pd.cut(df['column'], bins = label_ranges, labels = label_names)

# 매핑을 생성하고 대체한다.
mappings = {'Monday':'weekday', 'Tuesday':'weekday', 'Wednesday': 'weekday', 
            'Thursday': 'weekday', 'Friday': 'weekday', 
            'Saturday': 'weekend', 'Sunday': 'weekend'}

df['day_week'] = df['day'].replace(mappings)
profile
https://www.rarebeef.co.kr/

0개의 댓글