조금씩 꾸준히 완성을 향해

[Pandas] 함수 매핑(mapping) / apply, applymap, pipe 본문

Python/Numpy & Pandas

[Pandas] 함수 매핑(mapping) / apply, applymap, pipe

all_sound 2022. 10. 6. 22:56

함수 매핑


  • 시리즈 또는 데이터 프레임의 개별 원소를 특정 함수에 일대일 대응시키는 과정
    • 사용자가 직접 만든 함수 적용
  • apply(), applymap(), pipe()

 

시리즈 원소에 함수 매핑


series.apply(매핑함수) : 매핑 함수에 시리즈의 모든 원소를 하나씩 입력하고 리턴

# 라이브러리 import
import seaborn as sns
import pandas as pd
# 타이타닉의 age, fare 열 선택 후 새로운 열 ten 추가, 모든 데이터는 숫자 10
df = sns.load_dataset('titanic')[['age', 'fare']]
df['ten'] = 10
df.head(4)
 

# 임의의 객체 n에 숫자 10을 더하는 add_10(n) 사용자 함수 정의 
def add_10(n):
  return n+10
# 객체 a와 b를 더하는 add_two_obj(a, b) 함수 정의
def add_two_obj(a, b):
  return a + b
# apply로 매핑
sr1 = df.age.apply(add_10) # 괄호생략가능
sr2 = df.age.apply(add_two_obj, b=10) # 인자가 두개이기 때문에 나머지 하나 지정
sr3 = df.age.apply(lambda x: x+10) # 람다함수 사용
# 시리즈 출력(결과 동일)
print(sr1)
print(sr2)
print(sr3)

 

데이터 프레임 원소에 함수 매핑


dataframe.applymap(매핑함수)  - apply()의 기능에 포함되기 때문에 사용도 낮음

# df에서 age, fare 열 선택해서 add_10 함수 적용
df[['age', 'fare']].applymap(add_10)

 

데이터프레임 각 행, 열에 함수 매핑


 

df.apply(매핑함수, axis=0 or 1)) : 데이터프레임의 열 또는 행에 대해 함수를 적용

# 시리즈를 입력받아 결측치인지 확인하는 함수 정의
def missing_value(series):
  return series.isnull()
df.apply(missing_value) #axis=0이 디폴트 값

#시리즈의 최대값에서 최소값을 뺀 결과를 반환하는 함수 정의
def min_max(series):
  return series.max()-series.min()
df.apply(min_max)  # 열단위 적용

df.apply(min_max, axis=1)  # 행단위 적용

# 람다 함수 적용
# total, avg 열 생성
df['total'] = df.apply(lambda x : x.sum(), axis=1)
df['avg'] = df.apply(lambda x : x.mean(), axis=1)
df

pipe 


pipe(매핑함수)

    • 매핑함수가 반환하는 리턴값에 따라 pipe 메소드가 반환하는 객체의 종류가 결정
    • 데이터프레임, 시리즈, 개별 값 모두 반환 가능
  • apply vs pipe
    • apply는 일차적으로 시리즈 형태로 반환 (시리즈+시리즈 = 데이터프레임 가능), 스칼라 값 반환 불가
    • pipe의 경우 바로 DataFrame으로 반환 가능
  • pipe가 대부분의 경우를 잘 커버함
    • 주의! pipe는 axis 옵션이 없어서 axis=1 지정이 불가능
# 함수 정의
def missing_value(x):  # NaN값 확인
  return x.isnull()
def missing_count(x):  # NaN값의 개수 확인
  return x.isnull().sum()
def total_num_missing(x):  #NaN값의 개수의 합 확인
  return x.isnull().sum().sum()
# DataFrame 반환
df.pipe(missing_value).head(4)

# Series 반환
df.pipe(missing_count)

# Scalar 반환
df.pipe(total_num_missing) 
# output: 177

 

  • pipe 대신 apply를 사용한다면
# DataFrame 반환
df.apply(missing_value).head(4) #가능!

# Series 반환
print(df.apply(missing_count)) # 가능!
# Scalar 반환
print(df.apply(total_num_missing)) 
# 불가능! 이론적으로는 에러가 나야함 => 자체적으로 시리즈로 반환