함수
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를 사용하면 보다 직관적임을 알 수 있다.
'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 |