2019.08.27 Apply 메소드 심화, 두 개 이상의 index, columns 활용하기

오늘 보실 예시 코드입니다.




import pandas as pd

df=pd.read_excel('apply_심화_예제.xlsx')

def tot_calc(price, num):
    return price*num
df['total']=df.apply(lambda x: tot_calc(x['price'],x['num']),axis=1)
df


사용할 예제 엑셀입니다.






사용한 도구들입니다


- pandas, pandas.apply





최근에 알았는 데, apply 함수는 칼럼 하나(혹은 인덱스 한 줄)만 받는 게 아니더군요! 꽤나 유용하게 쓸 수 있을 것 같아서 예시 코드와 예제를 만들어 가져왔습니다.




일단, 코드의 목적은 각 물품의 총 가격을 구하는 것 입니다. 쉽게 설명하자면, 각 물품에 가격과 개수가 책정되어 있는데, 그 두 요소를 곱해 값을 구하고 새로운 열을 만들어 내는 게 이번 할 일입니다.



다른 건 다 필요 없고 핵심이 될 코드는 이 한 줄 입니다.









df['total']=df.apply(lambda x: tot_calc(x['price'],x['num']),axis=1)



apply 함수에는 매개값으로 함수를 받는다는 사실을 전에 알게 되셨을 겁니다.

그래서 저번에 apply를 활용할 때는, 굳이 함수를 만들지 않고 lambda를 이용해 임의로 함수를 정의하여 사용했었죠.

하지만 위의 테이블에서 두 개의 칼럼을 활용해야 한다면, lambda로는 쉽지 않을 뿐더러 함수 조차 어떻게 짜야 할지 감이 안잡힐 것입니다.

하지만 위의 방식, 즉 lambda와 임의 지정함수를 적절히 조합한다면 여러개의 칼럼을 효율적으로 활용할 수 있게됩니다.

apply가 어떻게 작동하는지 몇 가지 실험을 통해 확인하면 이해가 빠를 것 입니다.






def check(test):
    print(test)

df.apply(check)


테스트 겸 해서 새로운 함수를 정의하고, 특정 칼럼이 아닌 데이터프레임 자체를 apply에 적용해 봤습니다. 결과는 다음과 같습니다.





보시면 알겠지만, 각 칼럼들을 순서대로 읽어서 출력하고, 마지막으로 apply를 적용한 데이터프레임을 출력합니다.

코드를 보면 알겠지만 함수에 반환하는 값이 없기 때문에 전부 None으로 들어가 있습니다.

이것만 보면 어느정도 감이 잡히실 것 입니다. 한 함수 내에서 칼럼 여러 개를 Series 형태로 가지고 놀 수 있다는 이야기이지요.

지금 건은 lambda를 쓰지 않고 그대로 함수에 넣어봤습니다. 그렇다면 맨 위의 예제 코드 처럼 lambda에 함수를 동시에 사용하면 어떤 결과가 발생할까요?






def check(test, test2):
    print(test,test2)

df.apply(lambda x: check(x['price'],x['num']), axis=1)



이 코드의 결과는 다음과 같습니다.





Series를 하나 하나 가져오는 게 아닌, Series 내의 원소를 하나 씩 가져옵니다. 그것도 칼럼 두개에서 말이죠!

추가로 칼럼을 하나 더 만들어서 넣어볼까요?







df['test'] = 0

def check(test, test2,test3):
    print(test,test2,test3)

df.apply(lambda x: check(x['price'],x['num'],x['test']), axis=1)




데이터프레임에 'test'라는 칼럼을 추가하고, 칼럼 내 모든 값을 0으로 지정해 두었습니다. 함수에는 총 3개의 칼럼을 전달하구요. 결과는 다음과 같습니다.






보시다시피 3개의 칼럼이 전부 읽히는 것을 확인 할 수 있습니다.

칼럼으로 읽는 것 말고도, 인덱스를 기준으로 읽는 방법도 있습니다. 그것도 그렇게 어렵지 않습니다.






def check(test, test2):
    print(test,test2)

df.apply(lambda x: check(x['a'],x['b']))



apply의 매개 변수인 'axis' 를 지우거나, 혹은 'axis = 0'으로 설정하면 됩니다. 애당초 'axis'의 기본값이 0 이므로, 귀찮으면 안 적으면 됩니다.

그리고 함수에 보내는 매개값의 경우, '칼럼 명'이 아니라 '인덱스 명'을 입력해야 하는 것을 잊지 마세요. 저는 'a'와 'b' 값을 입력했습니다.

위의 코드 결과는 다음과 같습니다.





'a'가 가진 값 1000과 3, 'b'가 가진 값 3000과 1을 출력했습니다. 결과로 나오는 데이터프레임(혹은 series)도 기존과는 차이를 보이는데요,

전에는 인덱스를 기준으로 결과값들을 받아왔지만, 지금은 칼럼을 기준으로 결과값을 받아오게 됩니다.



그러면 원래 목표로 했던, 'price' * 'num' 값으로 이루어진 칼럼을 만드는 코드를 확인해 보겠습니다.



def tot_calc(price, num):
    return price*num

df['total']=df.apply(lambda x: tot_calc(x['price'],x['num']),axis=1)
df


이것도 그렇게 복잡한 것이 아닙니다.

함수를 하나 정의해둡니다. 'price', 'num' 값을 받아 두 값을 곱한 것을 반환하게 만듭니다.

그리고 새로운 칼럼인 'total'칼럼을 만듭니다. 'DataFrame_name['column_name'] = ~~' 이런 식으로 정의하면 데이터프레임에 새로운 칼럼을 정의합니다.

정의한 칼럼에 apply함수를 사용합니다. 칼럼들을 참조하여 만드므로 'axis = 1'을 매개값으로 주고, lambda를 정의한 다음 미리 만들어둔 곱하기 함수를 넣어둡니다. 함수에 보낼 값은 'price'와 'num' 칼럼입니다.

결과는 다음과 같습니다.






두개의 값을 곱한 칼럼이 만들어진 것을 확인할 수 있습니다.



pandas의 기능이 정말 무궁무진 합니다. 단순 엑셀 계산 작업부터 복잡한 통계 계산까지. 그것도 기존 엑셀로는 계산하기 복잡한 대량의 값들 조차 코드 몇 줄로 손쉽게 계산을 할 수 있습니다.

저도 아직 배우는 입장이라 많은 것을 알고 있지 않지만, 새로운 것을 배울 때 마다 블로그에 업로드 할 생각입니다.



https://github.com/pakupoko/blog_code


이제부터 코드나 예제 파일을 깃헙에 업로드 할 예정입니다. 막 시작해서 볼것은 없지만 점차 업로드 해 나간다면 코드 사전으로써 충분히 써먹을 수 있을 거라 생각합니다.




Pandas의 더 새롭고 효과적인 기능을 배우길 고대하며 이 글을 마칩니다.

댓글