Python/Pandas

[Pandas] 파이썬 판다스 행, 열에 함수 적용 : pd.transform()

jimmy_AI 2021. 12. 29. 14:50
반응형

파이썬 판다스 데이터프레임 함수 적용 : pd.transform()

안녕하세요. 지난 번에 다뤘던 apply 함수에 이어, 이번에는 판다스 데이터프레임의

각 행, 열에 함수를 적용할 수 있는 좀더 간단한 방법인 transform 함수의 예제를

살펴보도록 하겠습니다.

 

궁금하신 분들을 위하여

지난 번에 다룬 apply 함수 사용법에 대한 글의 링크는 아래에 첨부해두겠습니다.

 

[Pandas] 파이썬 데이터프레임 열, 행에 함수 적용 - apply 함수

파이썬에서 판다스를 이용하여 데이터프레임 작업을 하다보면 특정 column이나 row에 원하는 작업을 시키고 싶은 경우가 많을 것입니다. 이번 포스팅에서는 간단하지만 알아두면 굉장히 요긴한

jimmy-ai.tistory.com

두 함수의 세부적인 용도나 결과 형태의 차이는 여기서는 깊게 다루지는 않고,

이 차이에 대한 내용은 추후에 기회가 된다면 따로 다루겠으며,

여기서는 transform 함수의 예제에 집중하여 글을 작성해보도록 하겠습니다.

 

참고로, 이 글은 판다스 transform 함수의 공식 문서 내용에 기반하여 작성되었습니다.

 

pd.transform 함수 기본 예제(모든 열에 적용)

우선, 다음과 같은 간단한 데이터프레임이 있다고 가정해보겠습니다.

import pandas as pd

df = pd.DataFrame({'col1' : [1, 3, 5], 'col2' : [2, 4, 6], 'col3' : ['a', 'b', 'c']})
print(df)
# 결과
   col1  col2 col3
0     1     2    a
1     3     4    b
2     5     6    c

세 개의 열을 가지고 있으며,

col1, col2는 숫자형, col3은 문자열 자료형으로 이루어진 데이터프레임입니다.

 

이제 이 열에 간단하게 lambda로 구현된 곱셈 연산을 수행해보겠습니다.

참고로, 곱셈 연산은 숫자형, 문자열 자료형 모두에서 지원하는 점에 참고해주세요.

print(df.transform(lambda x : x * 2))
# 결과
   col1  col2 col3
0     2     4   aa
1     6     8   bb
2    10    12   cc

col1, col2 열은 숫자 값이 2배가 되었고, col3 열은 문자가 두 글자씩으로 늘어났습니다.

 

만일, 일부 column에서만 지원하는 연산 형태를 넣으면 오류가 발생할 수 있습니다.

print(df.transform(lambda x : x + 2))
# 결과
TypeError: can only concatenate str (not "int") to str

문자열 자료형에는 + 2 라는 숫자 덧셈은 허용하지 않아 TypeError가 발생했습니다.

다만, 이런 경우 뒤에서 설명할 리스트에 함수 목록을 넣는 방법을 사용하면

연산이 가능한 column에만 적용할 수 있습니다.

 

참고로 def 형태로 작성된 함수의 경우도 적용하는 데에는 문제가 없습니다.

def mul_2(x):
    return x * 2

print(df.transform(mul_2))
# 결과
   col1  col2 col3
0     2     4   aa
1     6     8   bb
2    10    12   cc

 

pd.transform 여러 함수 동시 적용

만일 리스트에 여러 함수의 목록을 묶어서 넣어준다면,

각 column마다 각 연산을 실행한 결과들을 일일히 출력해줍니다.

 

다만, 특정 column에는 연산이 불가능한 경우는 이 방법을 적용하면

필터링하여 가능한 column들에만 결과를 적용해서 보여줄 수 있습니다.

 

만일 2를 더하는 add_2, 'k'를 뒤에 붙이는 add_k, 그리고 넘파이에서 제공하는

exp 함수 총 3가지를 동시에 적용하면 어떻게 될까요? 아래 예시를 살펴보겠습니다.

숫자형 자료형에 가능한 연산은 add_2와 exp연산이고,

문자열 자료형에 가능한 연산은 add_k이기에

각 column에 가능한 연산의 조합들이 수행된 결과를 살펴볼 수 있었습니다.

반응형

transform과 groupby 연계 사용

groupby 함수와 연계하여 사용할 경우, 각 행에 groupby 함수의 결과를 가져와

적용하는 코드가 매우 간단해집니다. 이에 대한 의미를 이해해보기 위하여

다음 예시 데이터프레임을 살펴보겠습니다.

df = pd.DataFrame({'name' : ['a', 'a', 'b', 'b'], 'score' : [10, 15, 8, 6]})
# 데이터프레임 상태
  name  score
0    a     10
1    a     15
2    b      8
3    b      6

df.groupby('name')['score'].mean()
# 그룹화 결과
name
a    12.5
b     7.0

만일 name을 기준으로 각 name의 score 평균을 구해보면 위와 같이 계산이 됩니다.

 

이제 그룹화 결과에 .mean()이 아니라 transform을 적용해보겠습니다.

df.groupby('name')['score'].transform(np.mean)
# transform 결과
0    12.5
1    12.5
2     7.0
3     7.0

원래 데이터프레임의 각 row의 name에 해당하는 평균 점수가 반영되어

4개의 행이 모두 출력된 것을 확인할 수 있었습니다.

 

 

transform 함수 axis 설정 및 인덱스, 열 이름 활용

마지막으로 조금 복잡한 예시인 인덱스, 열 이름을 활용한 예제를 살펴보겠습니다.

transform 함수에는 axis 인자를 설정 가능한데, 0으로 설정하면 인덱스를 기준으로,

1로 설정하면 열 이름을 기준으로 데이터들을 가져올 수 있습니다.

 

먼저, 가장 앞의 예제에서 사용했던 데이터프레임을 다시 가져와

0번과 1번 인덱스의 값을 더하여 살펴보겠습니다.

인덱스를 기준으로 값을 가져와야 하기에 axis = 0으로 설정했습니다.

df = pd.DataFrame({'col1' : [1, 3, 5], 'col2' : [2, 4, 6], 'col3' : ['a', 'b', 'c']})

df.transform(lambda x : x[0] + x[1], axis = 0)
# 결과
col1     4
col2     6
col3    ab

col1에서는 가장 앞 데이터 두개인 1과 3이,

col2에서는 2와 4가, col3에서는 'a'와 'b'가 더해진 결과가

각각 열들을 기준으로 반환된 것을 확인해볼 수 있었습니다.

 

이번에는 col3의 값과 col1의 값을 각 행마다 불러와서

col3의 값을 col1의 수만큼 반복하여 출력하는 상황을 생각해보겠습니다.

여기서는 열 이름을 기준으로 값을 불러와야해서 axis = 1로 설정했습니다.

df = pd.DataFrame({'col1' : [1, 3, 5], 'col2' : [2, 4, 6], 'col3' : ['a', 'b', 'c']})

df.transform(lambda x : x['col3'] * x['col1'], axis = 1)
# 결과
0        a
1      bbb
2    ccccc

각 행의 col3 열 데이터인 'a', 'b', 'c'를 col1 열 데이터인 1, 3, 5회 만큼씩

반복하여 출력된 결과를 반환했습니다.

 

참고로 이 기능은 apply 함수에서도 동일하게 적용이 가능한 방법이며,

def를 이용한 함수 등에서는 아주 복잡한 기능도 구현이 가능하니

잘 활용하시면 매우 유용할 것으로 생각됩니다.