Home » 레퍼런스 » PYTHON » python groupby 로 그룹별로 원소들을 모아봅시다.

python groupby 로 그룹별로 원소들을 모아봅시다.

python groupby 클래스는, 특정한 값을 기준으로 모으는 역할을 합니다. sql에서 group by와 유사한 성격을 지닌다고 할 수 있겠습니다. 복잡한 케이스에 대해서는 pandas 등의 라이브러리를 참고할 것을 권합니다. 이 글에서는 itertools에 있는 것에 대해 다룹니다.


itertools의 groupby

먼저 해당 클래스에 대한 설명을 보겠습니다.

[그림 1] python groupby 클래스

먼저, 이것이 무엇을 하는 것인지 볼 필요가 있는데요.

  • make an iterator
  • consecutive (연이은) keys and groups
  • iterable한 것으로부터

이터레이터를 만드는데, 연속적으로 등장하는 같은 group에 대한 무언가를 만듭니다. key가 따로 주어지지 않으면, element를 가지고 groupping을 하게 됩니다. key function을 주는 예제는 아래에서 후술 하겠습니다. 그리고, 이것을 제대로 이용하려면, sort를 하는 것이 필수입니다. 정말 중요하니 이 부분은 별 5개.

[그림 2] 예제 1번 프로그램

먼저, 예제 1번을 보겠습니다. itertools의 groupby가, 연이은 key와 group 으로부터 이터레이터를 돌려준다 되어 있어요. 실제로, 해당 클래스는

  • 키 값
  • group 화가 된 iterator

를 쌍으로 리턴하게 됩니다. 이 프로그램이 어떻게 수행되는 것인지 그림으로 다시 그려보겠습니다.

먼저 앞에 a, a는 ‘a’로, 뒤에 b, b는 ‘b’라는 원소로 묶입니다. 따라서, 4번째 줄의 for loop가 순회할 때, 첫 번째 key 값은 ‘a’, 다음 key 값은 ‘b’가 되겠네요. 그런데, 보세요. items에 대해서 또 for loop를 돌았단 말이지요.

items는 iterator의 일종입니다.

이를 굳이 그림으로 그리면 위와 같습니다. 고로 각 items를 순회하면 key가 a일 때에는 a, a가, b일 때에는 b, b 순서대로 순회가 될 겁니다.

[그림 3] 예제 1번 프로그램의 결과

결과를 볼까요? key값이 a일 때, 4번째 줄에 의해 a, a가, key 값이 b일 때에는 b, b가 출력됩니다. 이제, 조금 더 발전된 예제를 봅시다.

[그림 4] 예제 2번 프로그램

우리는, 같은 키에 대해서 모아진 것들을 list 형태로 출력하고 싶습니다. 어떻게 해야 할까요? itertools의 groupby가 key와 iterator를 돌려주게 되는데요. list(iterator)는 이터레이터의 순회 결과를 list로 변환해 줍니다.

따라서, 5 ~ 6번째 줄과 같이 입력해 주면 됩니다.

[그림 5] 예제 2번 프로그램의 결과

결과는 위와 같습니다. 결국 items는 그룹별로 수집된 결과를 iteration하기 위한 이터레이터라는 사실을 이용한 것 뿐입니다.


python groupby 의 key function

그룹화 할 기준을 custom하게 설정할 수 있을까요? key function으로 가능합니다. 책의 장르와, 이름이 담긴 정보가 있습니다. 우리는 이를, 책의 장르에 대해서 묶으려고 해요. 그렇다면, 그룹화 할 기준이 무엇인가요? 책의 장르이지요.

[그림 6] 예제 3번 프로그램 1

데이터는 위와 같이 들어와요. 각 item에 대해서 type과 name이 있어요. 일단, 그룹화가 제대로 동작하기 위해서는, sort를 해야 합니다. 9번째 함수가 이를 수행합니다.

정렬이 되었다면, 이제 group 화를 할 수 있습니다.

[그림 7] 예제 3번 프로그램 2

11번째 줄을 보면, key 함수로, lambda k: k.get(“type”)을 넣었음을 볼 수 있습니다. 이는, 책의 type을 그룹핑 기준으로 삼는다는 의미입니다.

[그림 8] 예제 3번 프로그램의 결과

결과를 볼까요? 장르 computer은 이름이 computer, c++인 책이 있습니다. 그리고, 장르 math는 math와 math2가 있다는 결과를 출력합니다. 만약에 정렬을 하지 않았다면 어떻게 동작할까요?

[그림 9] 정렬을 해야 하는 이유

제대로 동작하지 않습니다. 이는, 같은 키가 연속적인 경우에 대해서만 묶이기 때문입니다. 정렬을 하지 않았다면, 아래 그림과 같이 되겠지요.

그러면 어떤 상황이 그려질까요?

  • 1번 원소와 2번 원소는 같은 그룹이 아니니 별개로 묶입니다.
  • 2번 원소와 3번 원소 또한 같은 그룹이 아니므로 별개로 묶입니다.
  • 3번 원소와 4번 원소도 마찬가지입니다.

조심해야 할 부분입니다. 당연한 이야기겠지만, 정렬을 할 때 key 함수와 그룹 key 함수하고 같아야 합니다. 왜 그렇게 해야 하는지는 찬찬히 고민해 보시는 것도 좋습니다.

Leave a Comment

15 − 8 =