【pandas_flavor】Pandas DataFrame의 메소드 추가

TL;DR



BEFORE
dataframe_ = dataframe.loc[(dataframe.time == 'pre') & \
                           (dataframe.group == 'exp') & \
                           (dataframe.cond == 'a'), :]
sns.regplot(x='mood', y='score', data=dataframe_)

↓↓↓

AFTER
dataframe.by(time='pre', cond='exp', group='a').regplot(x='trait', y='score')

pandas_flavor 을 사용하면 좋아하는 메소드를 pandas DataFrame (및 Series)에 추가 할 수 있습니다.

동기 부여



Long 형식의 데이터에서 조건에 맞는 부분을 추출하는 것은 귀찮다!

예를 들어 이런 데이터가 있다고 합니다.



피험자 50명을 두 그룹(group: exp, ctrl)으로 나누어 각각에 무슨 개입을 했다는 설정입니다.
개입 전후(time: pre, post)에서 과제를 실시하고, 과제 중 두 조건(cond: a, b)에서의 성적(score)을 측정했습니다.
동시에 과제를 하고 있을 때의 기분(mood)도 조건(cond:a, b)마다 측정했습니다. 1

측정 데이터는 위의 이미지처럼 long 형식으로 정리하면 그 후의 해석이 쉬워지네요.

그런데, 여러가지 해석을 하기 전에 일단,
pre에서 exp군의 과제 조건 a일 때의 score와 mood의 상관관계를 플롯하기로 하자.

이상의 조건에 맞는 행을 추출해 오므로 ↓ 이런 코드가 되네요.
dataframe_ = dataframe.loc[(dataframe.time == 'pre') & \
                           (dataframe.group == 'exp') & \
                           (dataframe.cond == 'a'), :]
sns.regplot(x='mood', y='score', data=dataframe_)

조건을 나타낸 bool형의 Series를 만들어, .loc 에 넣어 하고 있습니다.
음, 뭔가 더러워.
.query() 메소드를 사용하면 ↓ 이런 식으로도 쓸 수 있습니다.
dataframe_ = dataframe.query('time == "pre" & group == "exp" & cond == "a"')
sns.regplot(x='mood', y='score', data=dataframe_)

여기 쪽이 상당히 깨끗이 하고 있습니다만, 좀 더 좋은 느낌이 되지 않을까..query() 사용하는 방법은 bool의 Series를 사용하는 방법에 비해 느리다고 합니다.
역시, Long 형식의 데이터로부터 조건에 맞는 개소를 추출하는 것은 귀찮다!

Pandas DataFrame 메서드 추가



그렇다면 방법을 만들면 좋지 않습니다.

그래서 DataFrame에서 조건에 맞는 행을 추출하는 새로운 메소드를 만들어 봅시다.
↓ 이런 식으로 사용할 수 있다 .by() 메소드를 DataFrame에 새롭게 추가합니다.
dataframe.by(time='pre', cond='exp', group='a')

pandas_flavor 이라는 패키지를 사용하면 쉽게 이를 달성할 수 있습니다.

설치 방법



pip 또는,
pip install pandas_flavor

conda에서 한발입니다.
conda install -c conda-forge pandas_flavor

사용 예


import pandas_flavor as pf


@pf.register_dataframe_method
def by(self, **args):
    for key in args.keys():
        self = self.loc[self.loc[:, key] == args[key], :]
    return self

함수를 작성하고 데코레이터로 @pf.register_dataframe_method를 붙이면됩니다.
이 예제에서는 **args 그렇게하면 인수를 사전 형식으로받습니다.
이것에 의해, 각 인수로 지정한 행을 추출하고 있습니다.

게다가 seaborn의 각종 함수를 메소드화시키는 것도 좋네요.
@pf.register_dataframe_method
def regplot(self, **args):
    return sns.regplot(data=self, **args)



라고, 이런 느낌입니다.
pandas.Series에 메소드를 추가하고 싶다면 @pf.register_series_method 에서 같은 것을 할 수있는 것 같습니다.

이번 예는…, 아무튼 .query() 사용하면 좋은 생각도 합니다만, 여러가지 응용을 할 수 있을 것 같습니다.



말할 필요도 없지만, 모든 곳에서 올린 심리학 실험입니다. 숫자는 랜덤 모듈에서 생성됩니다.

좋은 웹페이지 즐겨찾기