개발/Python

#12 Preprocessing (with Pandas)

dev-bleck 2022. 8. 31. 14:09

Dataframe 병합하기

  • concat
    • 수직 또는 수평 병합
    • pd.concat 함수에 dataframe 객체를 list에 담아서 전달
pd.concat([df, df]) # default : axis = 0
  • merge
    • 매우 자주 사용
    • how argument를 이용해 left or inner join을 결정. default는 inner join
pd.merge(<left df>, <right df>, on = "기준 column명", how = "left")
  • cabin의 등장 빈도수를 특성으로 추가하고 싶다면?
# 먼저 cabin의 index와 index별 개수를 추출
tmp = df["cabin"].value_counts().reset_index()
tmp.columns = ["cabin", "cabin_cnt"]
tmp

tmp 출력

# df 복사본 features 생성
features = df.copy()
# features와 tmp를 cabin을 기준으로 left merge
# 만약 on을 생략하면 동일한 column명을 기준으로 merge
features = pd.merge(features, tmp, on = "cabin", how = "left")
features

features 출력

  • merge되는 column이 다수인 경우
# 각 항구에 대하여 pclass별 운임료의 평균과 티켓의 다양성을 집계
agg_dict = {"fare" : "mean", "ticket" : "nunique"}
tmp = features.groupby(["embarked", "pclass"]).agg(agg_dict).reset_index()
# merge되는 column명 변경
tmp = tmp.add_prefix("feature_").reset_index()
features = pd.merge(features, tmp, how = "left", on = ["embarked", "pclass"])

apply 메소드

  • Series, Dataframe에 대한 단순한 집계가 아닌, 구체적인 로직을 적용할 때 사용
  • 각 데이터에 대해 조건 검사 등과 같은 복잡한 처리 가능
  • apply 메소드에 우리가 정의한 함수(call-back 함수)를 넣어주면 됨
  • 항구별 sibsp column과 parch column의 합계의 평균을 구하고 싶다면?
    • agg 메소드로는 불가능. agg 메소드는 각 column에 대해서만 집계 가능
def do_apply(x):
    return (x["sibsp"] + x["parch"]).mean()
df.groupby("embarked").apply(do_apply)
>>> embarked
    C    0.770370
    Q    0.455285
    S    0.974891
    dtype: float64
  • apply의 대상이 되는 데이터의 구조에 따라 다르게 처리하거나, 축 개념이 있음
  • Series에 대한 apply : 축 개념이 없고 한 행씩 처리
df["gender"].apply(lambda x: 1 if x == "male" else 0)
>>> 0       1
    1       0
    2       0
    3       0
    4       1
           ..
    1304    1
    1305    0
    1306    1
    1307    1
    1308    1
    Name: gender, Length: 1309, dtype: int64
  • Dataframe에 대한 apply
    • 축 개념이 잆음
    • axis = 0 : 행 방향, column 단위로 처리(default : axis = 0)
    • axis = 1 : 열 방향, 행 단위로 처리
def do_apply(x):
    print(x.shape)
    return x

tmp = df.apply(do_apply) # column 단위로 print
>>> (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)
    (1309,)

def do_apply(x):
    print(x.shape)

tmp = df2.apply(do_apply, axis = 1)
>>> (13,)
    (13,)
    (13,)
    (13,)
    (13,)
  • groupby에 대한 apply : dataframe이 넘어감
def do_apply(x):
    display(x)
       print("=" * 50) # 구분선
    return x

tmp = df.groupby("embarked").apply(do_apply)
  • argument 전달 예시
age_mean = df["age"].mean()
age_mean
>>> 29.484339190221544
# 항구 별 평균 나이와 전체 평균 나이의 차이를 집계
def do_apply(x, age_mean):
    return x["age"].mean() - age_mean # 전체평균과 어떠한 그룹화된 평균의 차이
# apply에 대한 call-back 함수에 대해 추가 argument를 전달하고 싶다면,
# keyword argument 전달 방식으로 하면 됨
df.groupby("embarked").apply(do_apply, age_mean = age_mean)
>>> embarked
    C    1.889735
    Q   -1.248567
    S   -0.389361
    dtype: float64
  • pandas에서 progress bar 사용하기
from tqdm.auto import tqdm
tqdm.pandas() # 초기화. pandas에서 progress_apply를 사용할 수 있게 됨
import time # 너무 금방끝나면 못 보니까 딜레이 주기

def do_apply(x):
	time.sleep(0.01)
    return x
tmp = df.progress_apply(do_apply, axis = 1)

tmp 출력

728x90