본문 바로가기
IT & 데이터 사이언스/Python

[Python Data Analytics] Python을 활용한 데이터 전처리(2)

by 바른 호랑이 2023. 6. 20.
728x90
반응형

 Python을 활용한 데이터 전처리

 

[Python Data Analytics] Python을 활용한 데이터 전처리(1)

안녕하세요. 바른 호랑이입니다. 이번 게시글에서는 Python을 활용한 데이터 전처리 방법에 대해 알아볼 예정입니다. 데이터 분석이라고 하면 많은 사람들이 AI, 머신러닝, 딥러닝과 같은 부분들

data-is-power.tistory.com

안녕하세요. 바른 호랑이입니다.

이번 게시글에서는 저번 게시글에 이어서 Python을 활용한 데이터 전처리 방법에 대해 알아볼 예정입니다.

이전 게시글에서 누락, 중복 데이터 처리 및 데이터 표준화에 대해서 알아본 것에 이어서 함수적용방법, 열 순서변경 및 분리방법, 값 필터링 방법, 데이터프레임 병합 , 조인, 분리, 그룹핑 방법들에 대해서 알아볼 예정입니다. 실습환경은 기존과 동일하게 Colab을 활용하여 진행하였으며, 이전 게시글에서 다룬 내용이 궁금하신 분들은 위의 게시글을 참고해주시면 되겠습니다.

※ 실습파일

Python_DataAnalysis_07(Data_Preprocessing).ipynb
0.05MB

# 필요 패키지 설치
!pip install numpy
!pip install pandas
!pip install sklearn
!pip install scipy

# 경고 메세지 삭제
import warnings
warnings.filterwarnings(action='ignore')

# 필요 패키지 로드
import numpy as np
import pandas as pd
import seaborn as sns

# 필요 데이터 셋 로드
df = sns.load_dataset('titanic')

# 개별 원소에 함수 매핑하는 방법
# 사용자 함수 작성
def add_10(n):
  return n+10

def add_two_object(a, b):
  return a+b

# apply함수를 사용하여 개별 원소에 함수 매핑
print(df[['age', 'fare']].head(3), end='\n\n')
print(df['age'].head(3).apply(add_10), end='\n\n')
print(df[['age', 'fare']].head(3).apply(add_10, axis=0), end='\n\n')
print(df.head(3).apply(lambda x: add_two_object(x['age'], x['fare']), axis=1), end='\n\n')

# lamda함수 사용
print(df['age'].head(3).apply(lambda x: x+10), end='\n\n')

# applymap을 활용하여 2개 이상의 열에 함수 매핑하여 적용하기
print(df[['age', 'fare']].head(3).applymap(lambda x: x+10))

# pipe함수를 사용하여 데이터프레임 객체에 함수 매핑하기
# 사용자 함수 작성
def missing_value(x): # 각 열의 NaN 찾기
  return x.isnull()

def missing_count(x): # 각 열의 NaN 개수 반환
  return missing_value(x).sum()

def total_number_missing(x): # 데이터프레임의 총 NaN 개수
  return missing_count(x).sum()

df_rslt = df.pipe(missing_value)
series_rslt = df.pipe(missing_count)
value_rslt = df.pipe(total_number_missing)

print(f'{df_rslt} \n\n, {series_rslt} \n\n {value_rslt}')

# 열 순서 변경해서 출력하기
reversed_columns = list(df.columns.sort_values(ascending=False))
print(df[reversed_columns].head(), end='\n\n')

# 열 분리
df_dow = sns.load_dataset('dowjones')
dates = df_dow['Date'].astype('str').str.split('-')
print(dates[0:4], end='\n\n')

# 분리된 정보를 각각의 새로운 열에 담아 추가하기
df_dow['Year'] = dates.str.get(0)
df_dow['Month'] = dates.str.get(1)
df_dow['Day'] = dates.str.get(2)
print(df_dow.head(), end='\n\n')

# 데이터 프레임 필터링
print(df[((df['age'] >= 10) & (df['age'] < 20)) | (df['age'] >= 60)].age.value_counts(dropna=False).sort_index(), end='\n\n')

# isin() 메소드 활용
df[df.sibsp.isin([3, 4, 5])].head()

# 데이터프레임 합치기
# concat으로 연결하기 // 열의 개수가 다를 때에는 더 큰 값에 맞춰서 출력됨 - Default : outer join
t_df_01 = pd.DataFrame(
                        {
                            'a' : [1, 2, 3, 4]
                          , 'b' : [5, 6, 7, 8]
                          , 'c' : [9, 10, 11, 12]
                        }, index=[0, 1, 2, 3]
                      )
t_df_02 = pd.DataFrame(
                        {
                            'a' : [1, 2, 3, 4]
                          , 'b' : [5, 6, 7, 8]
                          , 'c' : [9, 10, 11, 12]
                          , 'd' : [13, 14, 15, 16]
                        }, index=[3, 4, 5, 6]
                      )

print(pd.concat([t_df_01, t_df_02]), end='\n\n')
print(pd.concat([t_df_01, t_df_02], ignore_index=True), end='\n\n') # 기존 인덱스를 삭제하고 새롭게 인덱스 부여
print(pd.concat([t_df_01, t_df_02], ignore_index=False, axis=1), end='\n\n') # 열 방향으로 이어붙이기
print(pd.concat([t_df_01, t_df_02], axis=1, join='inner'), end='\n\n') # join 옵션 값 변경

# merge로 병합하기 - SQL의 join과 유사
t_df_03 = df.iloc[2:5, [3, 6]]
t_df_04 = df.iloc[3:6, [3, 6]]
print(pd.concat([t_df_03, t_df_04], axis=0), end='\n\n')

merge_inner = pd.merge(t_df_03, t_df_04)
print(merge_inner, end='\n\n')

merge_outer_00 = pd.merge(t_df_03, t_df_04, how='outer')
print(merge_outer_00, end='\n\n')

merge_outer_01 = pd.merge(t_df_03, t_df_04, how='outer', on=['age', 'fare'])
print(merge_outer_01, end='\n\n')

merge_outer_02 = pd.merge(t_df_03, t_df_04, how='outer', on=['age'])
print(merge_outer_02, end='\n\n')

merge_outer_03 = pd.merge(t_df_03, t_df_04, how='left', on=['age', 'fare'])
print(merge_outer_03, end='\n\n')

merge_outer_04 = pd.merge(t_df_03, t_df_04, how='left', on=['age'])
print(merge_outer_04, end='\n\n')

merge_outer_05 = pd.merge(t_df_03, t_df_04, how='right', on=['age', 'fare'])
print(merge_outer_05, end='\n\n')

merge_outer_06 = pd.merge(t_df_03, t_df_04, how='right', on=['age'])
print(merge_outer_06, end='\n\n')

'''
* join() 메소드의 개념과 merge() 함수와의 차이점
- 기본적으로 join()메소드는 merge()함수를 기반으로 만들어졌기에 작동방식이 서로 비슷함.
join() 메소드는 두 데이터프레임의 행 인덱스를 기준으로 결합하는 것이 Default라는 것이
다르나, on=keys 옵션을 설정하면 행 인덱스 대신 다른 열을 기준으로 결합하는 것이 가능함.
join시 Default 옵션은 Left Join임.
'''
t_df_03 = df.iloc[2:5, [3, 6]]
t_df_04 = df.iloc[3:6, [3, 6]]
print(pd.concat([t_df_03, t_df_04], axis=0), end='\n\n')

# 열 이름이 같은게 있으면 중복시 이름 조건을 변경하여주는 옵션이 반드시 들어가야함.
join_inner = t_df_03.join(t_df_04, lsuffix='_left', rsuffix='_right')
print(join_inner, end='\n\n')

join_outer_00 = t_df_03.join(t_df_04, how='outer',lsuffix='_left', rsuffix='_right', on='age')
print(merge_outer_00, end='\n\n')

'''
* 그룹 연산
- 그룹 연산은 데이터를 집계, 변환, 필터링하는데 효율적이며,
 분할(split), 적용(apply), 결합(combine)이라는 3가지 단계로 이루어져 있음.
'''

# groupby() 메소드를 사용하여 그룹객체 만들기(분할)
grouped = df.groupby(['class'])
for key, group in grouped:
  print('key : ', key)
  print('number', len(group))
  print(group.head(), end='\n\n')
  
  # 연산 메소드 적용
average = grouped.mean()
print(average)

# 특정 그룹만 추출
print(grouped.get_group('Third').head())

# 여러 열을 기준으로 분할 및 그룹객체 만들기
grouped_two = df.groupby(['class', 'sex'])
for key, group in grouped_two:
  print('key : ', key)
  print('number', len(group))
  print(group.head(), end='\n\n')
  
# 연산 메소드 적용
average = grouped_two.mean()
print(average)

# 데이터 집계(aggreagation)하기
print(grouped.std(), end='\n\n')
print(grouped.var(), end='\n\n')
print(grouped.mean(), end='\n\n')

# agg() 메소드 적용해서 최대최소차이 구하기 -- 이어서 확인하기 230619
def min_max(x):
  return x.max()-x.min()

print(grouped.agg(min_max))

# 여러 함수를 각 열에 동일하게 적용하여 집계
agg_all = grouped.agg(['min', 'max'])
print(agg_all, end='\n\n')

# 각 열마다 다른 함수를 적용
agg_sep = grouped.agg({'fare':['min', 'max'], 'age':'mean'})
print(agg_sep, end='\n\n')

'''
* agg() 메소드와 transform() 메소드의 차이
- agg() 메소드는 각 그룹별 데이터에 연산을 위한 함수를 구분 적용후 그룹별로 연산 결과를 집계하여 반환
- transform() 메소드는 그룹별로 구분하여 각 원소에 함수를 적용하나 그룹별 집계가 아닌 각 원소의 본래 인덱스와
열 이름을 기준으로 연산 결과를 반환한다는 차이가 있음.
'''

# Z-score 계산하기 - agg() 메소드 사용
def z_score(x):
  return (x-x.mean()) / x.std()

for key, group in grouped.age:
  print(f'* origin : {key}\n{group.agg(z_score).head(3)}\n')

print(f'\n\n{grouped.age.transform(z_score)}.head()')

# 그룹 객체 필터링 - 데이터의 개수가 200개 이상인 값만 필터링
group_fillter = grouped.filter(lambda x: len(x) >= 200)
print(group_fillter['class'].unique(), sep='\n\n') # Second는 빠짐

# 각 그룹별 요약 통계정보 집계
agg_grouped = grouped.apply(lambda x: x.describe())
print(agg_grouped, end='\n\n')

# 피벗 활용하기
pdf1 = pd.pivot_table(
                        df # 피벗할 데이터프레임
                      , index='class' # 행 위치에 들어갈 열
                      , columns='sex' # 열 위치에 들어갈 열
                      , values='survived' # 데이터로 사용할 열
                      , aggfunc=['mean', 'sum'] # 데이터 집계함수
                      )
print(pdf1, end='\n\n')

pdf2 = pd.pivot_table(
                        df # 피벗할 데이터프레임
                      , index=['class', 'sex']  # 행 위치에 들어갈 열
                      , columns='survived' # 열 위치에 들어갈 열
                      , values=['age', 'fare'] # 데이터로 사용할 열
                      , aggfunc=['mean', 'sum'] # 데이터 집계함수
                      )
print(pdf2, end='\n\n')

# 멀티 인덱스 데이터 호출방법
print(grouped_two.mean().age, end='\n\n')
print(grouped_two.mean().loc[('First', 'female')], end='\n\n')
print(grouped_two.mean().age.xs('male', level='sex'), end='\n\n')
print(grouped_two.mean().age.xs(('Second', 'male')), end='\n\n')
print(pdf2.xs(('Second', 'male'), level=[0, 'sex']), end='\n\n')
print(pdf2.xs('mean', axis=1), end='\n\n')
print(pdf2.xs(('mean', 'age'), axis=1), end='\n\n')

P.S 더 나은 개발자가 되기위해 공부중입니다. 잘못된 부분을 댓글로 남겨주시면 학습하는데 큰 도움이 될 거 같습니다

728x90
반응형

댓글