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

Pandas(3)

by 생각하는 이상훈 2023. 8. 23.
728x90

함수

DataFrame에 함수를 적용하는 메서드에 대해서 알아보자.


apply

apply 메서드는 DataFrame에 함수를 적용하여 반환하는 메서드이다.
함수에 전달되는 객체는 Seires형식이며 DataFrame의 index(axis=0)이냐 columns(axis=1)이냐에 따라 다르다.
최종반환 유형은 적용된 함수에 따라 정해지지만 result_type을 지정하여 변경이 가능하다.

 

기본 사용법
df.apply(func, axis=0, raw=False, result_type=None, args=(), kwargs)
function : 각 행이나 열에 적용할 함수이다.
axis : {0 : Index / 1 : columns} 함수를 적용할 축이다.
row : {True : ndarray / False : Series} 함수에 전달할 축의 형식이다.
True ndarray형태로 전달하고 False Series형태로 전달합니다. 기본적으로 Series이다.
result_type : {expand / reduce / broadcast} 반환값의 형태를 결정한다.

expand이면 배열 형태를 기준으로 열을 확장한다.

reduce인 경우는 그대로 Series형태로 반환한다.

broadcase인 경우 기존 열 형식대로 확장하여 반환한다.(열의 수가 같아야한다.)

 

예시

col = ['col1','col2','col3']
row = ['row1','row2','row3']
data = [[1,2,3],[4,5,6],[7,8,9]]
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

print(df.apply(np.sqrt))
>>
          col1      col2      col3
row1  1.000000  1.414214  1.732051
row2  2.000000  2.236068  2.449490
row3  2.645751  2.828427  3.000000

print(df.apply(np.sum))
>>
col1    12
col2    15
col3    18
dtype: int64

print(df.apply(np.prod,axis=0))
>>
col1     28
col2     80
col3    162
dtype: int64

print(df.apply(np.prod,axis=1))
>>
row1      6
row2    120
row3    504
dtype: int64

result_type에 따른 차이

print(df.apply(lambda x : [1,2,3]))
>>
      col1  col2  col3
row1     1     1     1
row2     2     2     2
row3     3     3     3

print(df.apply(lambda x : [1,2,3], axis=1,result_type='expand'))
>>
      0  1  2
row1  1  2  3
row2  1  2  3
row3  1  2  3

print(df.apply(lambda x : [1,2,3], axis=1,result_type='reduce'))
>>
row1    [1, 2, 3]
row2    [1, 2, 3]
row3    [1, 2, 3]
dtype: object

print(df.apply(lambda x : [1,2,3], axis=1,result_type='broadcast'))
>>
      col1  col2  col3
row1     1     2     3
row2     1     2     3
row3     1     2     3

applymap

applymap 메서드는 객체의 각 요소에 함수를 적용하는 메서드이다.
즉, apply메서드와는 다르게 DataFrame의 각 요소 하나하나에 함수를 적용하여 스칼라 값을 반환한다.

 

기본 사용법
df.apply(func, axis=0, raw=False, result_type=None, args=(), kwargs)
func : 단일 값을 반환하는 함수이다.
na_action : {None / 'ignore} NaN의 무시 여부이다. 'ignore'이면 NaN을 함수로 전달하지 않는다.

 

예시

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

print(df.applymap(lambda x : x**2,na_action='ignore'))
>>
      col1  col2  col3
row1     1     4     9
row2    16    25    36
row3    49  <NA>    81

pipe

pipe 메서드는 함수를 연속적으로 사용할 때 유용한 메서드이다.
특히 함수가 인수를 사용할 때 pipe 메서드를 사용하면 보다 직관적으로 적용할 수 있다.

 

기본 사용법
df.pipe(func, args, kwargs)
func : 함수이다.
arg : 함수의 인수이다.
kwargs : dict 형태의 함수의 인수이다.

 

만약 함수 3개가 아래와 같이 있다고 해자.
f1(data, arg1), f2(data, arg1, arg2, f3(data, arg3)
f1 > f2 > f3 순서로 포함되게 함수를 사용한다고 하면 아래와 같이 함수를 사용해야 한다.
df=f1( f2( f3( data,arg3='c' ),arg2='b1',arg3='b2' ),arg1='a' )
이는 어떤 arg가 어떤함수인지 직관적으로 볼 수 없다. 이때, pipe함수를 사용할 수 있다.
df=data.pipe(f3, arg3='c').pipe(f2, arg2='b1', arg3='b2').pipe(f3, arg3='c')

 

예시

org_data = pd.DataFrame({'info':['삼성전자/3/70000','SK하이닉스/2/100000']})
print(org_data)
>>
              info
0     삼성전자/3/70000
1  SK하이닉스/2/100000

def code_name(data):
    result=pd.DataFrame(columns=['name','count','price']) 
    df = pd.DataFrame(list(data['info'].str.split('/'))) # '/ ' 로 구분하여 문자열을 나누어 리스트에 넣음
    result['name'] = df[0] # 여기엔 첫번째 값인 이름이 입력
    result['count']= df[1] # 여기엔 두번째 값인 수량이 입력
    result['price']= df[2] # 여기엔 세번째 값인 가격이 입력
    result = result.astype({'count':int,'price':int}) # count와 price를 int로 바꿈(기존str)
    return result
print(code_name(org_data))
>>
     name  count   price
0    삼성전자      3   70000
1  SK하이닉스      2  100000

def value_cal(data,unit=''):
    result = pd.DataFrame(columns=['name','value']) 
    result['name'] =data['name'] # 이름은 기존거를 가져옴
    result['value']=data['count']*data['price'] # value는 count * price를 입력함
    result = result.astype({'value':str}) # value를 str로 변경(단위를 붙이기 위함)
    result['value']=result['value']+unit # 단위를 붙임
    return(result)

input=code_name(org_data)
print(value_cal(input,'원'))
>>
     name    value
0    삼성전자  210000원
1  SK하이닉스  200000원

위와 같이 code_name(data)라는 (종목명/수량/가격)형태인 문자열 data를 입력받아서 각각으로 분리하고 수량과 가격의 dtype을 int로 변경하는 함수와 value_cal(data,unit=' ')라는 가격과 수량을 곱한다음에 단위로 unit arg를 붙이는 함수를 세팅해두고 pipe를 이용하는 경우와 그렇지 않은 경우를 비교해보자.

#pipe 사용x
print(value_cal(code_name(org_data),'원'))
>>
     name    value
0    삼성전자  210000원
1  SK하이닉스  200000원

#pipe 사용
print(org_data.pipe(code_name).pipe(value_cal,'원'))
>>
     name    value
0    삼성전자  210000원
1  SK하이닉스  200000원

pipe를 사용하면 보다 직관적임을 알 수 있다.


 

728x90

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

Pandas(4)  (1) 2024.01.31
Baekjoon Training #14888  (0) 2023.08.27
Pandas(2)  (0) 2023.08.21
Pandas(1)  (0) 2023.08.20
Baekjoon Training #1904  (0) 2023.08.18