728x90
반응형
※ Python을 활용한 데이터 전처리
안녕하세요. 바른 호랑이입니다.
이번 게시글에서는 저번 게시글에 이어서 Python을 활용한 데이터 전처리 방법에 대해 알아볼 예정입니다.
이전 게시글에서 누락, 중복 데이터 처리 및 데이터 표준화에 대해서 알아본 것에 이어서 함수적용방법, 열 순서변경 및 분리방법, 값 필터링 방법, 데이터프레임 병합 , 조인, 분리, 그룹핑 방법들에 대해서 알아볼 예정입니다. 실습환경은 기존과 동일하게 Colab을 활용하여 진행하였으며, 이전 게시글에서 다룬 내용이 궁금하신 분들은 위의 게시글을 참고해주시면 되겠습니다.
※ 실습파일
# 필요 패키지 설치
!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
반응형
'IT & 데이터 사이언스 > Python' 카테고리의 다른 글
[Python Data Analytics] OpenAPI를 활용한 데이터 호출&적재 (0) | 2023.07.17 |
---|---|
[Python Data Analytics] Python을 활용한 Machine Learning (0) | 2023.06.23 |
[Python Data Analytics] Python을 활용한 데이터 전처리(1) (0) | 2023.06.19 |
[Python Data Analytics] Pandas를 활용한 데이터 개요확인 (0) | 2023.06.18 |
[Python Data Analytics] Pandas를 활용한 데이터 입출력 (0) | 2023.06.18 |
댓글