본문 바로가기
데이터 분석

Pandas DataFrame - 데이터전처리

by ma_ro 2020. 3. 1.

column 사이의 상관계수 ( correlation )

  • corr 함수를 통해 상관계수 연산 ( -1, 1 사이의 결과 )
  • 연속성( 숫자형 ) 데이터에 대해서만 연산
  • 인과관계를 의미하진 않음
  • 1에 가까울 수록 같이 변화, -1에 가까울 수록 역변화
dataFrame.corr()

 

NaN값 처리

NaN값 조회

dataFrame.info()
#NaN 값이 몇개 있는지 확인하기 위해서 기본적 정보를 출력해봄.

dataFrame.isna()
#NaN이 true인 dataFrame 반환

dataFrame['컬럼명'].isna()
#NaN이 true인 특정 컬럼의 불리언 시리즈 반환

 

NaN값 처리

삭제

dataFrame.dropna()
#그냥 NaN이 있는 row를 지워버림

dataFrame.dropna(subset=['Age', 'Cabin'])
#특정 컬럼 지정

dataFrame.dropna(axis=1)
#NaN이 있는 column 삭제

 

값 대체

dataFrame['컬럼명'].fillna(대체값)
#dataFrame['Age'].fillna(dataFrame['Age'].mean(), inplace=true)
#inplace 옵션으로 값 자체를 바꿀수도 있음

 

숫자형, 범주형 데이터 처리

  • 숫자형 ( Numerical Type ) 데이터
    • 연속성을 띄는 숫자로 이루어진 데이터
    • Age, Fare
  • 범주형 ( Cateforical Type ) 데이터
    • 연속적이지 않은 값을 갖는 데이터
    • Name, Sex, Cabin
    • 숫자형 타입이어도 개념적으로 범주형으로 처리해야할 데이터
    • Pclass, 우편번호

 

변수 타입 변환하기

  • 범주형으로 처리해야할 데이터의 타입을 변환한다.
  • astype 함수 사용
dataFrame['Pclass'] = dataFrame['Pclass'].astype(str)

 

필요한 값으로 변환하기

  • 구체적 나이가 아니라, 나이대가 필요한 경우 원하는 값으로 변환
  • 변환 로직을 함수로 만들어서 적용하여 일괄 변환한다.
  • 적용시 loop 문이 아닌 apply 함수를 사용하여 loop 문 사용을 최소화한다.
# 변환 로직을 함수화
import math
def age_categorize(age):
    if math.isnan(age):
        return -1
    return math.floor(age / 10) * 10

# apply 함수로 로직 적용
dataFrame['Age'].apply(age_categorize)

 

범주형 데이터 전처리 : One-hot encoding

  • 범주형 데이터는 분석단계에서 계산이 어렵기 때문에 숫자형으로 변환이 필요
  • 범주형 데이터의 각 범주를 각각의 column으로 변경
  • 값은 해당할 경우 1, 그렇지 않을 경우 0으로 처리
  • pandas.get_dummies 함수를 통해 변경
    • drop_first : 첫번째 범주 표시 여부. 없을 경우 다른 범주 값을 통해서 값 유추 가능
pd.get_dummies(dataFrame, columns=['Pclass', 'Sex'], drop_first=False)
# Pclass_1, Pclass_2, Pclass_3 || Sex_female, Sex_male

 

Group by

  • SQL의 group by와 개념적으로 동일, 사용법은 유사하다.
  • 그룹 데이터를 생성한다.
  • 아래 3단계를 적용하여 데이터를 grouping한다.
    • 데이터 분할
    • operation 적용
    • 데이터 병합
  • pandas.core.groupby.generic.DataFrameGroupBy

 

groups

  • 각 그룹과 그룹에 속한 index를 dict 형태로 표현
gender_group = df.groupby('Sex')
gender_group.groups

{'female': Int64Index([  1,   2,   3,   8,   9,  10,
             ...
             880, 882, 885, 887, 888], dtype='int64', length=314),
 'male': Int64Index([  0,   4,   5,   6,  7,
             ...
             883, 884, 886, 889, 890], dtype='int64', length=577)}

 

groupping 함수

  • 그룹 데이터에 적용 가능한 통계 함수 ( NaN은 제외하여 연산 )
    • count : 데이터 개수
    • sum : 데이터의 합
    • mean, std, var : 평균, 표준편차, 분산
    • min, max : 최소, 최대값
gender_group = df.groupby('Sex')
gender_group.max()
# Sex컬럼으로 묶은 데이터의 각 컬럼별 max값

class_group = df.groupby('Pclass')
class_group.mean()['Survived']
# 클래스별 컬럼들의 평균 값중 'Survieved' 항목만 추출

 

복수 column groupping

  • column 리스트를 이용하여 복수 grouping 가능
  • multiindex를 갖는 dataframe이 생성됨
# 첫번째 인덱스만 선택 가능
df.groupby(['Pclass', 'Sex']).mean().loc[(2)]

# 인덱스 2개 다 선택 가능 # 두 번쨰 인덱스 선택만은 불가능
df.groupby(['Pclass', 'Sex']).mean().loc[(2, 'female')]

 

index를 이용한 group by

  • index를 기준으로 groupping 가능
    • 여기서 index 를 level로 선택가능
    • 첫번째 인덱스부터 0부터 증가
  • set_index 함수
    • column 데이터를 index 로 변경
  • reset_index 함수
    • 인덱스 초기화
  • 함수를 이용할 경우 기본적으로 index의 값을 함수에 적용
# pclass컬럼을 index로 설정
df.set_index('Pclass')

# 설정했던 인덱스롤 다시 초기화
df.set_index(['Pclass', 'Sex']).reset_index()

# 1번째 인덱스를 기준으로 groupping하고 평균값 리턴
df.set_index('Age').groupby(level=0).mean()
import math
def age_categorize(age):
    if math.isnan(age):
        return -1
    return math.floor(age / 10) * 10

# 여기서 'Age'를 index로 삼았기 때문에 'Age'컬럼의 값들이 함수에 적용
df.set_index('Age').groupby(age_categorize).mean()['Survived']

 

Multiindex를 이용한 groupping

df.set_index(['Pclass', 'Sex']).groupby(level=[0, 1]).mean()['Age']
# df.groupby(['Pclass', 'Sex']).mean()['Age']
# 이거랑 똑같음

 

aggregate ( 집계 ) 함수 이용

  • aggregate 함수를 통해 그룹별 집계 결과도 같이 확인 가능
  • aggregate( 'numpy 함수')
df.groupby(['Pclass', 'Sex']).aggregate([np.mean, np.sum, np.std])
# 각 column 데이터의 numpy 함수값이 표시됨.

 

transform 함수

  • groupby시 index가 groupping한 컬럼이 된다.
  • 원래 형태로 groupping 데이터를 보고 싶을때 transform 함수를 사용한다.
  • 원래 index에서 결과 값만 groupping한 컬럼의 결과 값으로 보여준다.
  • 때문에 row 개수가 유지된다.
df.groupby('Pclass').transform(np.mean)

df['Age2'] = df.groupby('Pclass').transform(np.mean)['Age']
# 이런 식으로 결과 값으로 새로운 컬럼을 만들 수도 있다.

 

pivot, pivot_table 함수 이용

pivot

  • dataframe의 형태를 변경
  • 컬럼을 지정하여 인덱스, 컬럼, 데이터 순으로 사용 가능
df.pivot('index', 'column', 'data')
# index와 column은 꼭 필요
# data가 지정되지 않으면 남은 컬럼을 모두 data로 사용

pd.pivot(df, 'index', 'column', 'data')
# 이렇게도 사용 가능

 

pivot_table

  • 기능적으로 pivot과 동일
  • 중복되는 모호한 값이 있을 경우, aggregation 함수 사용하여 값을 채움
pd.pivot_table(df, index='요일', columns='지역', aggfunc=np.mean)

 

stack, unstack

  • stack
    • 컬럼에서 인덱스로 dataframe 변경
    • 데이터를 쌓아올리는 개념
  • unstack
    • 인덱스에서 컬럼으로 dataframe 변경
    • stack의 반대 관계
new_df = df.set_index(['지역', '요일'])
new_df.unstack(0)
# 첫 번째 index인 '지역'이 column으로 올라감

 

concat

  • default는 axis=0 세로로 병합
  • column 명이 같은 경우
    • axis=0, 1 상관 없음
  • column 명이 다른 경우
    • axis=0 이면 , 비는 값에 NaN이 들어감
    • sort 옵션으로 column 순서 설정을 해야함
# column명이 같은 경우
pd.concat([df1, df2], ignore_index=True)

# column명이 다른 경우
pd.concat([df1, df3], axis=0, sort=False)

 

dataFrame merge

  • SQL처럼 특정한 column을 기준으로 join이 가능
  • how 파라미터를 통해 join 방식 명시
pd.merge('DF 1번', 'DF 2번', on='join컬럼', how='inner')
  • 인덱스를 기준으로도 join 가능
pd.merge('DF 1번', 'DF 2번', left_index=True, right_index=True)

'DF 1번'.join('DF 2번', how='inner')

'데이터 분석' 카테고리의 다른 글

Pandas DataFrame - CRUD  (0) 2020.03.01
Pandas Series  (0) 2020.03.01
Numpy Broadcasting  (0) 2020.02.29
Numpy 기본 함수  (0) 2020.02.29
Numpy ndarray shape 변경  (0) 2020.02.29

댓글