본문 바로가기
Sketch (Programming Language)/Python

Pandas(4)

by 생각하는 이상훈 2024. 1. 31.
728x90

함수 연속 적용 (축별)

agg메서드는 apply와 비슷하게 함수를 적용하는 메서드이지만, 여러개의 함수를 동시에 적용할 수 있다는 장점이 있다. 또한 __name__을 통해 사용자정의 함수명을 따로 설정할 경우 그 이름을 사용한다는 점을 활용하여 함수를 사용한 DataFrame을 보다 깔끔하게 정리하는데도 용이하게 쓸 수 있다.

기본 형태는 다음과 같고 df.agg(func=None, axis=0, args, kwargs) 그 요소를 살펴보면 아래와 같다.
func : 함수이다.
axis :{0 : index(row) / 1 : columns} 축이다. (0은 행, 1은 열) 

arg : 함수의 인수이다.
kwargs : dict 형태의 함수의 인수이다.


예시

먼저 간단한 3x3짜리 데이터를 만들어보자.

df = pd.DataFrame([[1,4,7],[2,5,8],[3,6,9]])
print(df)
>>
   0  1  2
0  1  4  7
1  2  5  8
2  3  6  9

입력함수로는 먼저 np.함수 형태나 그냥 문자열 형태로의 입력이 가능하다.

#np함수의 경우

ex1 = df.agg(np.prod)
print(ex1)
>>
0      6
1    120
2    504
dtype: int64

#문자열일 경우

ex2 = df.agg('prod')
print(ex2)
>>
0      6
1    120
2    504
dtype: int64

 

lambda함수나 사용자 정의 함수를 사용할 수도 있다.
lambda함수를 사용할 경우 열 명칭은 <lambda>가 된다.

ex3 = df.agg([lambda x : min(x) * max(x)])
print(ex3)
>>
          0   1   2
<lambda>  3  24  63

사용자정의 함수를 사용하게되면 기본적으로 함수명 열 이름으로 설정이 된다.

def func_sub(input):
    return max(input)-min(input)
ex4 = df.agg([func_sub,'sum'])
print(ex4)
>>
          0   1   2
func_sub  2   2   2
sum       6  15  24

만약 함수명을 __name__메서드를 통해 따로 설정해주면 그 이름이 쓰인다.

 

여러 함수에 동시에 적용하려면 아래와 같이 list dict형태로 func값을 입력하면 된다.

list로 입력하는 경우

ex6 = df.agg(['min','max','sum','prod'])
print(ex6)
>>
      0    1    2
min   1    4    7
max   3    6    9
sum   6   15   24
prod  6  120  504

dict를 이용하는 경우 순서를 변경하는것도 가능하다.

ex7 = df.agg({2:'sum',0:'max',1:'min'})
print(ex7)
>>
2    24
0     3
1     4
dtype: int64


`axis`의경우 0이면 `index`, 1이면 `columns` 기준으로 연산을 진행한다.

ex2 = df.agg('prod', axis=0)
print(ex2)
>>
0      6
1    120
2    504
dtype: int64
ex3 = df.agg('prod', axis=1)
print(ex3)
>>
0     28
1     80
2    162
dtype: int64

함수 연속 적용 (요소별)

transform메서드는 agg와 비슷하게 함수를 적용하는 메서드이지만, 단일 요소별로 함수를 동시에 적용할 수 있다는 장점이 있다. 마치 apply와 applymap의 차이와 비슷하다.

사용법은 다음과 같이 agg와 같다. df.transform(func, axis=0, args, kwargs)


예시

먼저 간단한 3x3짜리 데이터를 다시 만들어보자.

Copycol = ['col1','col2','col3']
row = ['row1','row2','row3']
df = pd.DataFrame(data=[[10,40,70],[20,50,80],[30,60,90]],index=row,columns=col)
print(df)
>>
      col1  col2  col3
row1    10    40    70
row2    20    50    80
row3    30    60    90

 

입력함수로는 agg와 같이 np.함수 형태나 그냥 문자열 형태로의 입력이 가능하다.
np함수의 경우

ex1 = df.transform(np.sqrt)
print(ex1)
>>
          col1      col2      col3
row1  3.162278  6.324555  8.366600
row2  4.472136  7.071068  8.944272
row3  5.477226  7.745967  9.486833

문자열일 경우

ex2 = df.transform('sqrt')
print(ex2)
>>
          col1      col2      col3
row1  3.162278  6.324555  8.366600
row2  4.472136  7.071068  8.944272
row3  5.477226  7.745967  9.486833

lambda함수나 사용자 정의 함수를 사용할 수도 있다. 이때 agg와 다르게 기존 레이블이 표시된다.

ex3 = df.transform(lambda x : np.sqrt(x))
print(ex3)
>>
          col1      col2      col3
row1  3.162278  6.324555  8.366600
row2  4.472136  7.071068  8.944272
row3  5.477226  7.745967  9.486833



agg와 같이 list나 dict형태로 func값을 입력하는 경우 여러 함수를 동시에 적용할 수 있다.
다만 transform을 사용하면 list로 입력하는 경우 마치 multi index처럼 multi columns가 생성된다.

ex4 = df.transform(['exp','sqrt'])
print(ex4)
>>
              col1                    col2                    col3          
               exp      sqrt           exp      sqrt           exp      sqrt
row1  2.202647e+04  3.162278  2.353853e+17  6.324555  2.515439e+30  8.366600
row2  4.851652e+08  4.472136  5.184706e+21  7.071068  5.540622e+34  8.944272
row3  1.068647e+13  5.477226  1.142007e+26  7.745967  1.220403e+39  9.486833

agg와 같이 dict를 이용하면 순서를 변경하는것도 가능하다.

ex5 = df.transform({'col2':'exp','col1':'sqrt'})
print(ex5)
>>
              col2      col1
row1  2.353853e+17  3.162278
row2  5.184706e+21  4.472136
row3  1.142007e+26  5.477226

문자열 형식의 계산식 적용

eval메서드는 파이썬의 eval 메서드와 사용목적이 동일하여 문자열로 된 계산식을 적용한다.

사용방법은 아래와 같다.
df.eval(expr, inplace=False, kwargs)
expr : 문자열 형태의 계산식
inplace : {True / False} 계산된 값이 원본을 변경할지의 여부이다. 기본적으로 원본은 변경되지 않는다.


예시

먼저 기본적인 3x3 DataFrame을 만들어보자.

data = [[1,2,3],[4,5,6],[7,8,9]]
col = ['col1','col2','col3']
row = ['row1','row2','row3']
df = pd.DataFrame(data = data, index = row, columns= col)
print(df)
>>
      col1  col2  col3
row1     1     2     3
row2     4     5     6
row3     7     8     9


우선 col1*col2-col3의 값을 갖는 col4를 만들어보자. 'col4'='col1'+'col2'-'col3'를 문자열 그대로 사용한다.
계산이 적용된 col4열이 생성된 것을 확인할 수 있다.

print(df.eval('col4=col1*col2-col3'))
>>
      col1  col2  col3  col4
row1     1     2     3    -1
row2     4     5     6    14
row3     7     8     9    47

하지만 inplace인수가 기본값인 False이기 때문에 원본은 변경되지 않아서 원래대로 3X3 DataFrame이 출력된다.

 

inplace = True로 할 경우 원본이 변경되는것을 확인해보자.
이때 inplace = True로 할경우 사본이 생성되지 않기 때문에 print할 경우 None이 출력된다.

print(df.eval('col4=col1*col2-col3',inplace=True))
>>
None

하지만 원본은 변경되어있는것을 확인할 수 있다.

Copyprint(df)
>>
      col1  col2  col3  col4
row1     1     2     3    -1
row2     4     5     6    14
row3     7     8     9    47

 

728x90

'Sketch (Programming Language) > Python' 카테고리의 다른 글

프로그래머스 - 소수 만들기  (0) 2024.05.02
Pandas(5)  (0) 2024.02.04
Baekjoon Training #14888  (0) 2023.08.27
Pandas(3)  (0) 2023.08.23
Pandas(2)  (0) 2023.08.21