IT/언어

[python] pandas로 요소, 행, 열에 함수를 적용하는 map, applymapp, apply

개발자 두더지 2021. 5. 17. 23:46
728x90

적용할 함수, 대상에 따른 차이


 pandas의 객체(pandas.DataFrame, pans.Sries)에 함수를 적용할 경우, 어떠한 함수에 적용하는가 그리고 요소/행/열 어디에 적용할 것인가에 따라 사용하는 메소드가 달라진다.

  • Numpy함수의 인수로 pandas객체를 지정

     - 함수의 인수에 pandas객체를 지정하는 것이 가능하다.

     - 함수의 종류 및 인수의 설정에 따라 요소/행/열에 적용되는 방법이 다르다

     - pandas객체의 메소드로 사전에 정의되어 있는 함수도 있다.

  • pandas객체의 메소드에 함수를 적용

     - 요소(스칼라값)에 관한 함수

       + Series의 각 요소에 적용: map(), apply() 

       + DataFrame의 각 요소에 적용: applymap()

    - 행/열(1차원 배열)에 관한 함수

       + DataFrame의 각 행/ 각 열에 적용 : apply()

       + DataFrame의 특정 행/특정 열에 적용

 이번 포스팅에서는 아래와 같은 csv파일이 존재하고 있다고 가정하고 설명하도록 하겠다.

a,b,c,d
11,12,13,14
21,22,23,24
31,32,33,34

 csv 파일은 다음과 같이 Pandas의 pd.read_csv('파일경로')로 읽어들일 수 있다.

import pandas as pd
import numpy as np

df = pd.read_csv('data/src/sample_header.csv')
print(df)
#     a   b   c   d
# 0  11  12  13  14
# 1  21  22  23  24
# 2  31  32  33  34

 

 

Numpy함수의 인수로 pandas객체를 지정


 Numpy함수의 인수로 pandas를 지정할 수 있다.

요소로 적용

 Numpy의 유니버셜 함수(ufumc: 배열의 요소로 적용되는 함수)는 pandas객체의 각 요소에 적용될 수 있다.

 Numpy의 유니버셜 함수로는 다양한 함수가 있지만 예를 들면 절대값(fabs())이나 제곱근(sqrt()), log(log())등이 있다.

print(np.sqrt(df))
#           a         b         c         d
# 0  3.316625  3.464102  3.605551  3.741657
# 1  4.582576  4.690416  4.795832  4.898979
# 2  5.567764  5.656854  5.744563  5.830952

행/열에 적용

 Numpy배열의 모든 요소의 값을 계산하는 함수의 인수로 pandas객체를 지정하면, 기본적으로 pandas객체의 각 열에 대해 적용된다. 인수 axis=1로 지정하면, 각 행에 대해서 적용된다.

 최대 (amax()) 나 최소(amin()), 평균(mean())등 을 구할 때 유용하게 사용할 수 있다.

print(np.amax(df))
# a    31
# b    32
# c    33
# d    34
# dtype: int64

print(np.mean(df, axis=1))
# 0    12.5
# 1    22.5
# 2    32.5
# dtype: float64

(추가) pandas.DataFrame, pandas.Series 의 메소드

 최대, 최소, 평균, 분산 등은 pandas 객체의 메소드로써도 준비되어 있어 있다(물론 다른 함수들도 있다). 이 경우에도 기본적으로 각 열에 적용되며, axis=1로 지정하면 각 행에 적용된다.

print(df.max())
# a    31
# b    32
# c    33
# d    34
# dtype: int64

print(df.max(axis=1))
# 0    14
# 1    24
# 2    34
# dtype: int64

 

 

pandas객체의 메소드로 함수를 적용


 pandas객체의 메소드를 사용하여 요소나 행/열에 함수를 적용하는 것이 가능하다. python의 내장 함수, 유저가 정의한 함수 상관없이 적용할 수 있다. 물론 Numpy의 함수도 가능하다.

  • Series의 각 요소에 적용 : map(), apply()
  • DataFrame의 각 요소에 적용: applymap()
  • DataFrame의 각 행/각 열에 적용: apply()

 어떠한 메소드도 처리된 새로운 pandas객체를 리턴하고, 원래의 객체는 바뀌지 않는다. dropna()나 fillna()과 같이 인수 inplace는 없기 때문에, 원래의 객체 자체도 바꾸고 싶은 경우는 다음과 같이 할 수 있다.

df = df.applymap(function)

 즉, 새로운 객체를 원래의 객체에 대입하면 간단히 해결된다.

Series의 각 요소에 적용 : map(), apply()

python의 내장함수, 무명 함수(lambda)나 def로 정의한 함수를 map()혹은 apply()인수로 전달한다.

s = df['a']
print(s)
# 0    11
# 1    21
# 2    31
# Name: a, dtype: int64

f_brackets = lambda x: '[{}]'.format(x)
print(s.map(f_brackets))
# 0    [11]
# 1    [21]
# 2    [31]
# Name: a, dtype: object

def f_str(x):
    return str(x).replace('1', 'One').replace('2', 'Two').replace('3', 'Three').replace('4', 'Four')

print(s.map(f_str))
# 0      OneOne
# 1      TwoOne
# 2    ThreeOne
# Name: a, dtype: object

map()의 경우, 인수에 사전형dict를 지정하면 요소 치환이 된다. 또한 문자열에 대한 치환 등의 처리는 정의되어 있는 문자열 메소드를 이용한 방법을 통해 이루어진다. 향후에 시간이 된다면 이 부분에 대한 포스팅을 하도록 하겠다.

DataFrame의 각 요소에 적용: applymap()

위와 동일하게 Python의 내장 함수, 무명함수(lambda)나 def로 정의된 함수를 applymap()의 인수로 전달한다.

f_oddeven = lambda x: 'odd' if x % 2 == 1 else 'even'
print(df.applymap(f_oddeven))
#      a     b    c     d
# 0  odd  even  odd  even
# 1  odd  even  odd  even
# 2  odd  even  odd  even

DataFrame의 각 행/각 열에 적용: apply()

1차원 배열에 적용 가능한 함수를 apply()의 인수로 전달한다. 디폴트로는 각 행에 대해 적용되며, 열에 적용하기 위해서는 axis=1를 지정해줘야한다.

f_maxmin = lambda x: max(x) - min(x)
print(df.apply(f_maxmin))
# a    20
# b    20
# c    20
# d    20
# dtype: int64

print(df.apply(f_maxmin, axis=1))
# 0    3
# 1    3
# 2    3
# dtype: int64

 

DataFrame의 특정 행/특정 열에 적용

DataFrame의 특정 행/특정 열에[만 함수를 적용하는 별도의 함수는 없기 때문에,

  1) 행 / 열을 선택하고, Series로 map() 또는 apply()에 적용한다

  2) 원래의 행/열에 대입하여 덮어쓴다

위와 같은 순서로 처리한다.

df['b'] = df['b'].map(f_str)
print(df)
#     a         b   c   d
# 0  11    OneTwo  13  14
# 1  21    TwoTwo  23  24
# 2  31  ThreeTwo  33  34

df.iloc[2] = df.iloc[2].map(f_str)
print(df)
#           a         b           c          d
# 0        11    OneTwo          13         14
# 1        21    TwoTwo          23         24
# 2  ThreeOne  ThreeTwo  ThreeThree  ThreeFour

 

참고자료

https://note.nkmk.me/python-pandas-map-applymap-apply/

728x90