Python

[Python] collections.Counter 에 대해 알아보자

ilovedigital 2024. 8. 30. 17:35

 

예전에 특정 논문속에 있는 특정 박테리아들을 분류하고 찾는 작업을 한적이 있었다.

 

나는 그것을 간단한 파이썬을 통해 처리하고 있었는데 find() 로 해당 박테리아명이 현재 논문에 있는지 확인하고, 있다면 해당 박테리아명이 몇번이나 언급되었는지 등을 리스트 메서드 count() 로 수집하였다.

 

그런 와중에 이런 생각을 가지게 되었다.

 

count() 를 계속해서 호출해야하는게 너무 별로인거 같다

 

그런 와중에 collections 모듈의 Counter 를 알게 되었는데, 매우 편리한 기능이였다.

 

import collections

collections.Counter([iterable-or-mapping])¶

 

Counter 는 해당하는 반복가능한 자료구조 혹은 딕셔너리같은 매핑 가능한 객체에서 요소들의 개수를 세서 Counter 객체로 반환하며 그 카운트들을 딕셔너리 같은 형태로 반환한다. 예제로 한번 사용해보자

from collections import Counter

number_list = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

cnt = Counter(number_list)

print(cnt)
Counter({1: 4, 2: 4, 3: 4, 4: 4, 5: 4})

 

요소들을 Key : Value 형태로 정리해서 반환해준다. 이렇게 반환된 Counter 객체에서 cnt[1] 이런식으로 키값을 호출하면 그 값인 4 를 반환한다. 키값이 없다면 0 를 반환한다.

 

Counter 의 메서드들

most_common(n)

빈도가 높은 순으로 요소와 그 빈도를 딕셔너리 형태로 반환한다. n 으로 지정하면 상위 n 개의 요소만 반환한다.

 

from collections import Counter

number_list = [1, 2, 3, 1, 2, 3, 1, 2, 3, 5, 1, 2, 3, 4, 5, 1, 1, 2, 3]

cnt = Counter(number_list)

print(cnt.most_common())
print(cnt.most_common(1))
[(1, 6), (2, 5), (3, 5), (5, 2), (4, 1)]
[(1, 6)]

 

 

또한 신기하게도 Counter 객체 끼리는 덧셈, 뺄셈이 가능하며 교집합과 합집합이 가능하다.

 

from collections import Counter

alpabet_list = ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'd']

cnt = Counter(alpabet_list)
cnt2 = Counter(a=1, b=2, c=3, d=4)


print(cnt + cnt2)
print(cnt - cnt2)
print(cnt & cnt2)
print(cnt | cnt2)
Counter({'d': 6, 'c': 5, 'b': 4, 'a': 3})
Counter({'a': 1})
Counter({'b': 2, 'c': 2, 'd': 2, 'a': 1})
Counter({'d': 4, 'c': 3, 'a': 2, 'b': 2})

 

그 외에도 elements(), total() 등의 여러 메서드들이 있었지만 나는 주로 설명했던 위의 메서드들이나 요소들을 자주 활용했던 것 같다.

 

 

정리

해당 반복가능한 객체에서 단일 특정 값에 대해서 카운트를 알고 싶다면, 그대로 리스트등에서 제동하는 count() 를 사용해도 무방할것같다.

 

하지만 여러 값에 대해 반복적으로 카운트를 알아야한다면 collections.Counter 를 사용해보는 것이 매우 좋을것이다.

 

왜냐하면 count를 계속해서 호출하는 것은 성능면에서 비효율적이기 때문이다. collections.Counter 는 한번의 순회만으로 모든 요소의 빈도를 계산하기 때문이다.

 

참고 : Python Docs collections 파트

https://docs.python.org/ko/3/library/collections.html#collections.Counter