Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 Counter 클래스 완벽 가이드 – collections 모듈로 요소 개수 손쉽게 세기

Counter(카운터)는 동일한 값이 몇 번 추가되었는지를 자동으로 추적해 주는 컨테이너입니다. 파이썬의 Counter 클래스는 표준 라이브러리인 collections 모듈에 포함되어 있으며, 딕셔너리(dict)를 상속하는 서브클래스입니다.

파이썬 Counter의 기본 개념

Counter는 순서가 없는(unordered) 컬렉션으로 이해할 수 있습니다. 각 항목(item)은 딕셔너리의 로 저장되고, 해당 항목이 등장한 횟수는 으로 저장됩니다.

카운트 값은 양수, 0, 음수 모두 가능합니다. 키와 값에 대한 엄격한 제한은 없지만, 일반적으로 값은 숫자를 의도하며 필요하다면 다른 객체 타입도 저장할 수 있습니다.

Counter 초기화 방법 3가지

Counter는 세 가지 형태로 초기화할 수 있습니다. 생성자에 항목 시퀀스, 키와 카운트가 담긴 딕셔너리, 또는 키워드 인자를 전달하는 방식입니다.

import collections
print(collections.Counter(['a', 'b', 'c', 'a', 'b', 'b']))
print(collections.Counter({'a': 2, 'b': 3, 'c': 1}))
print(collections.Counter(a=2, b=3, c=1))

세 가지 방식 모두 동일한 결과를 출력합니다.

Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})

빈 Counter 생성 후 채우기

인자 없이 Counter를 생성하면 빈 객체가 만들어지며, 이후 update() 메서드를 통해 데이터를 추가할 수 있습니다.

import collections
c = collections.Counter()
print('Initial:', c)
c.update('abcddcba')
print('Sequence:', c)
c.update({'a': 1, 'd': 5})
print('Dict:', c)
Initial: Counter()
Sequence: Counter({'a': 2, 'b': 2, 'c': 2, 'd': 2})
Dict: Counter({'d': 7, 'a': 3, 'b': 2, 'c': 2})

update()는 기존 값을 덮어쓰지 않고 누적한다는 점이 중요합니다. 위 예제에서 'd'의 카운트가 2에서 5가 더해져 7이 된 것을 확인할 수 있습니다.

카운트 조회하기

Counter가 채워진 후에는 일반 딕셔너리 API와 동일한 방식으로 값을 조회할 수 있습니다.

import collections
c = collections.Counter('abcddcba')
for letter in 'abcdef':
    print('%s : %d' % (letter, c[letter]))
a : 2
b : 2
c : 2
d : 2
e : 0
f : 0

Counter는 존재하지 않는 키를 조회할 때 KeyError를 발생시키지 않습니다. 입력에서 한 번도 등장하지 않은 값(위 예제의 e, f)의 카운트는 자동으로 0을 반환합니다. 이는 일반 딕셔너리와 다른 편리한 특징입니다.

elements() 메서드

elements() 메서드는 Counter에 저장된 모든 항목을 카운트만큼 반복해서 반환하는 이터레이터(iterator)를 제공합니다.

import collections
c = collections.Counter('Python Counters')
c['z'] = 0
print(c)
print(list(c.elements()))
Counter({'t': 2, 'o': 2, 'n': 2, 'P': 1, 'y': 1, 'h': 1, ' ': 1, 'C': 1, 'u': 1, 'e': 1, 'r': 1, 's': 1, 'z': 0})
['P', 'y', 't', 't', 'h', 'o', 'o', 'n', 'n', ' ', 'C', 'u', 'e', 'r', 's']

반환되는 요소의 순서는 고정되어 있지 않으며, 카운트가 0 이하인 항목(위 예제의 'z')은 결과에서 제외됩니다.

most_common()으로 최다 빈도 항목 찾기

most_common() 함수를 사용하면 가장 많이 등장한 n개의 항목과 그 카운트를 손쉽게 확인할 수 있습니다. 아래 예제는 텍스트(또는 파일)에 포함된 문자의 빈도 분포를 계산한 뒤, 가장 흔한 다섯 글자를 출력합니다.

import collections
c = collections.Counter()
texts = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.'''
for word in texts:
    c.update(word.rstrip().lower())
print("Five most common letters in the texts:")
for letter, count in c.most_common(5):
    print("%s: %7d" % (letter, count))
Five most common letters in the texts:
i:      42
e:      38
t:      32
o:      29
u:      29

most_common()에 인자를 생략하면 전체 항목을 빈도순으로 정렬한 리스트를 반환합니다. 로그 분석, 단어 빈도 집계 등 실무에서 매우 유용하게 활용됩니다.

산술 및 집합 연산

Counter 객체는 여러 결과를 통합하기 위한 산술 연산과 집합 연산을 지원합니다.

  • + (덧셈): 두 Counter의 카운트를 더합니다.
  • - (뺄셈): 카운트를 빼며, 결과가 0 이하인 항목은 제거됩니다.
  • & (교집합): 양수인 최솟값(min)을 취합니다.
  • | (합집합): 최댓값(max)을 취합니다.
import collections
c1 = collections.Counter(['a', 'b', 'c', 'a', 'b', 'b'])
c2 = collections.Counter('alphabet')
print('C1:', c1)
print('C2:', c2)
print('\nCombined counts:')
print(c1 + c2)
print('\nSubtraction:')
print(c1 - c2)
print('\nIntersection (taking positive minimums):')
print(c1 & c2)
print('\nUnion (taking maximums):')
print(c1 | c2)
C1: Counter({'b': 3, 'a': 2, 'c': 1})
C2: Counter({'a': 2, 'l': 1, 'p': 1, 'h': 1, 'b': 1, 'e': 1, 't': 1})
Combined counts:
Counter({'a': 4, 'b': 4, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})
Subtraction:
Counter({'b': 2, 'c': 1})
Intersection (taking positive minimums):
Counter({'a': 2, 'b': 1})
Union (taking maximums):
Counter({'b': 3, 'a': 2, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})

연산을 통해 새로운 Counter가 생성될 때마다 카운트가 0 또는 음수인 항목은 자동으로 버려집니다. 따라서 결과에는 항상 유효한(양수 카운트의) 항목만 남게 됩니다.

정리

파이썬의 Counter는 딕셔너리를 확장한 강력한 빈도 계산 도구입니다. 리스트나 문자열에서 중복 항목을 세거나, 최빈값을 구하고, 여러 데이터 소스의 카운트를 병합할 때 반복문을 직접 작성하는 것보다 훨씬 간결하고 직관적인 코드를 작성할 수 있습니다. 데이터 분석, 로그 처리, 텍스트 마이닝 등 다양한 분야에서 적극적으로 활용해 보시기 바랍니다.