전처리가 쉬워지는 판다스 파이프라인


PNG


pdpipe 관련 글 목록


데이터 분석가들은 일반적으로 데이터 전처리 작업에 오랜 시간을 소요한다고 알려져있습니다. 반복적이고 번거로운 데이터 전처리 작업을 직관적이고 쉽게 만들어줄 파이썬 라이브러리가 공개되어 직접 사용해본 후기를 소개해드리겠습니다.


샘플 데이터 다운로드

캐글에 공개된 미국 주택 가격 데이터를 프로젝트 내 Data 디렉토리에 저장하겠습니다.


pdpipe 설치

터미널에서 다음과 같이 pdpipe를 설치합니다.

pip install pdpipe


심플한 전처리 파이프라인 만들기

import pandas as pd
import pdpipe as pdp

df = pd.read_csv('Data/USA_Housing.csv')


데이터 요약 결과

df.describe().T
count mean std min 25% 50% 75% max
Avg. Area Income 5000.0 6.858311e+04 10657.991214 17796.631190 61480.562388 6.880429e+04 7.578334e+04 1.077017e+05
Avg. Area House Age 5000.0 5.977222e+00 0.991456 2.644304 5.322283 5.970429e+00 6.650808e+00 9.519088e+00
Avg. Area Number of Rooms 5000.0 6.987792e+00 1.005833 3.236194 6.299250 7.002902e+00 7.665871e+00 1.075959e+01
Avg. Area Number of Bedrooms 5000.0 3.981330e+00 1.234137 2.000000 3.140000 4.050000e+00 4.490000e+00 6.500000e+00
Area Population 5000.0 3.616352e+04 9925.650114 172.610686 29403.928702 3.619941e+04 4.286129e+04 6.962171e+04
Price 5000.0 1.232073e+06 353117.626581 15938.657923 997577.135049 1.232669e+06 1.471210e+06 2.469066e+06


데이터 확인 결과

df.head()
Avg. Area Income Avg. Area House Age Avg. Area Number of Rooms Avg. Area Number of Bedrooms Area Population Price Address
0 79545.458574 5.682861 7.009188 4.09 23086.800503 1.059034e+06 208 Michael Ferry Apt. 674\nLaurabury, NE 3701...
1 79248.642455 6.002900 6.730821 3.09 40173.072174 1.505891e+06 188 Johnson Views Suite 079\nLake Kathleen, CA...
2 61287.067179 5.865890 8.512727 5.13 36882.159400 1.058988e+06 9127 Elizabeth Stravenue\nDanieltown, WI 06482...
3 63345.240046 7.188236 5.586729 3.26 34310.242831 1.260617e+06 USS Barnett\nFPO AP 44820
4 59982.197226 5.040555 7.839388 4.23 26354.109472 6.309435e+05 USNS Raymond\nFPO AE 09386


‘House_size’ 컬럼 추가하기

실수값을 갖는 컬럼 Avg. Area Number of Rooms을 사용해 서열 범주형 값을 갖는 컬럼 House_size를 만들어보겠습니다. 사분위수를 참고해 Small, Medium, 그리고 Big 이렇게 총 3개 등급을 갖도록 하겠습니다.

House_size

  • Small(~25%) : ~ 6.3
  • Medium(25%~75%) : 6.3 ~ 7.7
  • Big(75%~) : 7.7 ~
def size(n):
    if n <= 6.3:
        return 'Small'
    elif 6.3 < n <= 7.7:
        return 'Medium'
    else:
        return 'Big'

df['House_size'] = df['Avg. Area Number of Rooms'].apply(size)
df.head()
Avg. Area Income Avg. Area House Age Avg. Area Number of Rooms Avg. Area Number of Bedrooms Area Population Price Address House_size
0 79545.458574 5.682861 7.009188 4.09 23086.800503 1.059034e+06 208 Michael Ferry Apt. 674\nLaurabury, NE 3701... Medium
1 79248.642455 6.002900 6.730821 3.09 40173.072174 1.505891e+06 188 Johnson Views Suite 079\nLake Kathleen, CA... Medium
2 61287.067179 5.865890 8.512727 5.13 36882.159400 1.058988e+06 9127 Elizabeth Stravenue\nDanieltown, WI 06482... Big
3 63345.240046 7.188236 5.586729 3.26 34310.242831 1.260617e+06 USS Barnett\nFPO AP 44820 Small
4 59982.197226 5.040555 7.839388 4.23 26354.109472 6.309435e+05 USNS Raymond\nFPO AE 09386 Big


컬럼 삭제 파이프라인 객체 만들기

우선, 한 가지 오퍼레이션만 존재하는 가장 간단한 파이프라인을 추가해보겠습니다. 또, 추후 데이터 분석 과정에서는 이제 컬럼 Avg. Area Number of Rooms는 필요가 없다고 가졍해보겠습니다. 따라서 이 컬럼을 데이터셋에서 지우겠습니다.

pdpipedrop_age라는 파이프라인 객체를 하나 만들고, ColDrop 메소드를 판다스 데이터프레임에 적용해보겠습니다!

drop_age = pdp.ColDrop('Avg. Area Number of Rooms')
df2 = drop_age(df)

파이프라인에 의해 해당 컬럼이 제거된 결과입니다.

df2.head()
Avg. Area Income Avg. Area House Age Avg. Area Number of Bedrooms Area Population Price Address House_size
0 79545.458574 5.682861 4.09 23086.800503 1.059034e+06 208 Michael Ferry Apt. 674\nLaurabury, NE 3701... Medium
1 79248.642455 6.002900 3.09 40173.072174 1.505891e+06 188 Johnson Views Suite 079\nLake Kathleen, CA... Medium
2 61287.067179 5.865890 5.13 36882.159400 1.058988e+06 9127 Elizabeth Stravenue\nDanieltown, WI 06482... Big
3 63345.240046 7.188236 3.26 34310.242831 1.260617e+06 USS Barnett\nFPO AP 44820 Small
4 59982.197226 5.040555 4.23 26354.109472 6.309435e+05 USNS Raymond\nFPO AE 09386 Big


파이프라인 추가하기

파이프라인은 여러 단계의 작업을 수행할때 매우 유용합니다. + 연산자를 사용해 컬럼을 삭제하는 작업 외에 머신러닝 알고리즘을 활용할 수 있도록 원-핫 인코딩(One-Hot Encoding)하는 작업도 추가해보겠습니다.

pipeline이라는 파이프라인 객체를 하나 만들고, 컬럼 삭제 기능원-핫 인코딩 기능을 추가한 다음 이를 데이터프레임에 적용해보겠습니다.

pipeline = pdp.ColDrop('Avg. Area Number of Rooms')
pipeline += pdp.OneHotEncode('House_size')

df3 = pipeline(df)

즉, 먼저 ColDrop 메소드로 컬럼Avg. Area Number of Rooms를 지우는 파이프라인 객체를 생성했습니다. 그리고 파이썬의+= 문법으로 심플하게 OneHotEncode 메소드를 이 파이프라인 객체에 추가했습니다.

그 결과 컬럼 House_size_MediumHouse_size_Small가 원-핫 인코딩 작업에 의해 생성된 것을 확인할 수 있습니다!

df3.head()
Avg. Area Income Avg. Area House Age Avg. Area Number of Bedrooms Area Population Price Address House_size_Medium House_size_Small
0 79545.458574 5.682861 4.09 23086.800503 1.059034e+06 208 Michael Ferry Apt. 674\nLaurabury, NE 3701... 1 0
1 79248.642455 6.002900 3.09 40173.072174 1.505891e+06 188 Johnson Views Suite 079\nLake Kathleen, CA... 1 0
2 61287.067179 5.865890 5.13 36882.159400 1.058988e+06 9127 Elizabeth Stravenue\nDanieltown, WI 06482... 0 0
3 63345.240046 7.188236 3.26 34310.242831 1.260617e+06 USS Barnett\nFPO AP 44820 0 1
4 59982.197226 5.040555 4.23 26354.109472 6.309435e+05 USNS Raymond\nFPO AE 09386 0 0


로우 삭제 파이프라인 객체 만들기

위에서 만든 파이프라인 객체에 컬럼 삭제 외에 로우도 삭제할 수 있는 기능을 추가해보도록 하겠습니다. 주택 가격을 의미하는 컬럼 Price의 값이 250,000 미만인 컬럼은 분석에서 제외해야하는 상황이라고 가정해봅시다. ApplyByCol 메소드로 삭제할 행을 나타내는 컬럼 Price_tag 을 생성하는 기능을 파이프라인에 추가합니다. 이어서 ValDrop 메소드를 통해 조건을 만족하는 로우를 삭제하는 기능도 파이프라인에 추가합니다. 삭제 작업을 완료한 후 불필요한 컬럼인 Price_tag을 삭제하는 기능도 파이프라인에 추가해봅시다.

def price_tag(x):
    if x > 250000:
        return 'keep'
    else:
        return 'drop'
pipeline += pdp.ApplyByCols('Price', price_tag, 'Price_tag', drop=False)
df4 = pipeline(df)
print('df 로우 수 : ', len(df), '\ndf4 로우 수 : ', len(df4), sep='')
df4.head()
df 로우 수 : 5000
df4 로우 수 : 5000
Avg. Area Income Avg. Area House Age Avg. Area Number of Bedrooms Area Population Price Price_tag Address House_size_Medium House_size_Small
0 79545.458574 5.682861 4.09 23086.800503 1.059034e+06 keep 208 Michael Ferry Apt. 674\nLaurabury, NE 3701... 1 0
1 79248.642455 6.002900 3.09 40173.072174 1.505891e+06 keep 188 Johnson Views Suite 079\nLake Kathleen, CA... 1 0
2 61287.067179 5.865890 5.13 36882.159400 1.058988e+06 keep 9127 Elizabeth Stravenue\nDanieltown, WI 06482... 0 0
3 63345.240046 7.188236 3.26 34310.242831 1.260617e+06 keep USS Barnett\nFPO AP 44820 0 1
4 59982.197226 5.040555 4.23 26354.109472 6.309435e+05 keep USNS Raymond\nFPO AE 09386 0 0

위에서 정의한 함수 price_tag 를 컬럼 Price 에 적용해, 삭제할 로우를 표시하는 임시 컬럼 Price_tag 이 생성되었습니다. 아직 로우는 삭제되기 전입니다.


pipeline += pdp.ValDrop(['drop'], 'Price_tag')
df5 = pipeline(df)
print('df 로우 수 : ', len(df), '\ndf5 로우 수 : ', len(df5), sep='')
df5.head()
df 로우 수 : 5000
df5 로우 수 : 4990
Avg. Area Income Avg. Area House Age Avg. Area Number of Bedrooms Area Population Price Price_tag Address House_size_Medium House_size_Small
0 79545.458574 5.682861 4.09 23086.800503 1.059034e+06 keep 208 Michael Ferry Apt. 674\nLaurabury, NE 3701... 1 0
1 79248.642455 6.002900 3.09 40173.072174 1.505891e+06 keep 188 Johnson Views Suite 079\nLake Kathleen, CA... 1 0
2 61287.067179 5.865890 5.13 36882.159400 1.058988e+06 keep 9127 Elizabeth Stravenue\nDanieltown, WI 06482... 0 0
3 63345.240046 7.188236 3.26 34310.242831 1.260617e+06 keep USS Barnett\nFPO AP 44820 0 1
4 59982.197226 5.040555 4.23 26354.109472 6.309435e+05 keep USNS Raymond\nFPO AE 09386 0 0

삭제할 로우를 표시하는 임시 컬럼 Price_tag 의 값이 drop인 로우를 삭제한 결과입니다. 10개 로우가 삭제된 것을 알 수 있습니다. 다음 단계에서 임시 컬럼 Price_tag 을 삭제해보겠습니다.


pipeline += pdp.ColDrop('Price_tag')
df6 = pipeline(df)
print('df 로우 수 : ', len(df), '\ndf6 로우 수 : ', len(df6), sep='')
df6.head()
df 로우 수 : 5000
df6 로우 수 : 4990
Avg. Area Income Avg. Area House Age Avg. Area Number of Bedrooms Area Population Price Address House_size_Medium House_size_Small
0 79545.458574 5.682861 4.09 23086.800503 1.059034e+06 208 Michael Ferry Apt. 674\nLaurabury, NE 3701... 1 0
1 79248.642455 6.002900 3.09 40173.072174 1.505891e+06 188 Johnson Views Suite 079\nLake Kathleen, CA... 1 0
2 61287.067179 5.865890 5.13 36882.159400 1.058988e+06 9127 Elizabeth Stravenue\nDanieltown, WI 06482... 0 0
3 63345.240046 7.188236 3.26 34310.242831 1.260617e+06 USS Barnett\nFPO AP 44820 0 1
4 59982.197226 5.040555 4.23 26354.109472 6.309435e+05 USNS Raymond\nFPO AE 09386 0 0

임시 컬럼 Price_tag이 삭제된 결과입니다.


위에서 사용한 파이프라인 기능 정리

  • 특정 컬럼 삭제
  • 머신러닝 모델링을 위한 범주형 변수의 원-핫 인코딩
  • 사용자 정의 함수에 의해 삭제할 로우 태깅하는 컬럼 생성
  • 삭제할 값을 나타내는 태그에 따라 로우 삭제
  • 로우 삭제를 위해 임시로 생성한 태그 컬럼 삭제
pipeline = pdp.ColDrop('Avg. Area Number of Rooms')
pipeline += pdp.OneHotEncode('House_size')
pipeline += pdp.ApplyByCols('Price',price_tag,'Price_tag',drop=False)
pipeline += pdp.ValDrop(['drop'],'Price_tag')
pipeline += pdp.ColDrop('Price_tag')
df6 = pipeline(df)


(참고) 람다 이용한 로우 삭제

람다를 사용하면 훨씬 간단하게 로우 삭제가 가능합니다.

pipeline2 = pdp.RowDrop({'Price': lambda x: x <= 250000})
df7 = pipeline2(df)
print('df 로우 수 : ', len(df), '\ndf7 로우 수 : ', len(df7), sep='')
df7.head()
df 로우 수 : 5000
df7 로우 수 : 4990
Avg. Area Income Avg. Area House Age Avg. Area Number of Rooms Avg. Area Number of Bedrooms Area Population Price Address House_size
0 79545.458574 5.682861 7.009188 4.09 23086.800503 1.059034e+06 208 Michael Ferry Apt. 674\nLaurabury, NE 3701... Medium
1 79248.642455 6.002900 6.730821 3.09 40173.072174 1.505891e+06 188 Johnson Views Suite 079\nLake Kathleen, CA... Medium
2 61287.067179 5.865890 8.512727 5.13 36882.159400 1.058988e+06 9127 Elizabeth Stravenue\nDanieltown, WI 06482... Big
3 63345.240046 7.188236 5.586729 3.26 34310.242831 1.260617e+06 USS Barnett\nFPO AP 44820 Small
4 59982.197226 5.040555 7.839388 4.23 26354.109472 6.309435e+05 USNS Raymond\nFPO AE 09386 Big


pdpipe 관련 글 목록


태그:

카테고리:

업데이트:

댓글남기기