아는 만큼 보인다
[Pandas/Python] Pandas로 데이터 전처리할 때 method chaining (함수 연속적용) 직관적으로 하기 본문
데이터 전처리를 하다보면, 여러 개의 함수를 연속적으로 사용해야 할 때가 있다. 데이터와 분석 목적에 따라 전처리 과정은 몹시 길 수도 있는데, 이것을 잘 정리해주지 않으면 오류가 발생하기 쉽고 비효율적인 코드가 되거나, 미래의 나와 팀원이 이해하기 어려운 코드가 될 수 있다. 이번 글에서는 method chaining을 통해 좀 더 간결하고 직관적으로 데이터 전처리 코드를 짜는 방법에 대해 알아보고자 한다.
예시와 함께 보도록 하자! 예시는 Iris dataset과 함께 살펴보도록 하겠다.
Iris dataset의 table 구조는 다음과 같다.
data = pd.read_csv('Iris.csv')
data
Id | SepalLengthCm | SepalWidthCm | PetalLengthCm | PetalWidthCm | Species | |
---|---|---|---|---|---|---|
0 | 1 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa |
1 | 2 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
2 | 3 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
3 | 4 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
4 | 5 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
... | ... | ... | ... | ... | ... | ... |
여기서, SepalLengthCm
기준 4.5 이상인 것들만 필터링한 후, 각 Species
마다 데이터가 몇 개씩 있는지 count하고 싶다고 가정하자.
따로 method chaining을 사용하지 않는 경우, 코드는 다음과 같다.
# filter based on SepalLengthCm > 4.5
data = data[data['SepalLengthCm'] > 4.5]
# count data after grouping by "Species"
data = data.groupby("Species").count()
# Select "Id" column
data = data[["Id"]]
data
Id | |
---|---|
Species | |
Iris-setosa | 45 |
Iris-versicolor | 50 |
Iris-virginica | 50 |
SepalLengthCm
으로 필터링 한 후, Species
로 grouping하여 count()
를 사용하여 데이터 개수를 확인했다.
마지막으로, Id
column만 가져와 간단하게 결과를 확인했다.
어떤 것을 하려는지 잘 보이긴 하지만 코드가 너무 길고! 같은 변수명을 사용해서 코드 작성 과정에서 error prone할 수 있다.
(물론 변수명을 바꿔서(data1
, data2
, etc.) 약간의 문제를 해결할 수는 있으나, 그 경우 적용하려는 함수 개수에 따라 local variable의 수가 늘어나 복잡한 코드가 탄생할 수 있다)
이걸 조금 더 간단하게 할 수 있는데, 방법은 아래와 같다.
data = data[data['SepalLengthCm'] > 4.5].groupby("Species").count()[["Id"]]
data
Id | |
---|---|
Species | |
Iris-setosa | 45 |
Iris-versicolor | 50 |
Iris-virginica | 50 |
그냥 모든 함수를 다 이어주었다!
물론 지금은 적용하려는 함수가 많지 않아, 이렇게 되어 있어도 하려는 일이 무엇인지 충분히 알 수 있다.
그러나 column의 이름이 길거나 적용하려는 함수가 많아질 수록 코드는 끝도 없이 길어지고, 다른 사람이 보기에 직관적이지 않은 코드가 된다.
그럼 여기서 어떻게 더 개선할 수 있을까?
코드 양옆에 ()
를 넣어주고 함수별로 정리해주는 방법이 있다.
data = (
data
[data['SepalLengthCm'] > 4.5]
.groupby("Species")
.count()
[["Id"]]
)
data
Id | |
---|---|
Species | |
Iris-setosa | 45 |
Iris-versicolor | 50 |
Iris-virginica | 50 |
즉 단순히 코드를 ()
에 넣고, 실행하려는 각 함수별로 줄바꿈을 해주면 된다.
이렇게 해주면,
내가 나중에 다시 꺼내어 보아도 무엇을 하고 있는지 이해할 수 있고, 다른 사람이 보아도 차근차근 따라가기 쉬운 코드를 만들 수 있다!
또한 여러 의미 없는 변수를 따로 정의해주지 않아도 되고, 이후에 코드를 수정할 때에도 좀 더 빨리 할 수 있기도 하다!
참고로, 나는 기존에 R 유저였어서 %>%
를 사용해서 method chaining을 많이 했었는데 이번에 입사하며 pandas로는 그렇게 할 수 없을까 생각하게 되어 찾아보던 중 발견한 방법이다.
참고자료: https://towardsdatascience.com/the-flawless-pipes-of-python-pandas-30f3ee4dffc2