(파이썬) Counter 사용법

Counter

Counter 는 collections 아래에 정의된 사전(dict)의 서브 클래스로 일련의 집합에서 각 원소의 출현 횟수를 세어서 유지한다. 즉 원소:출현빈도의 사전이 생성된다. 생성된 카운터 사전은 일반 사전과 유사하게 키:값 쌍을 추가/삭제하거나 업데이트 할 수 있고, 각 원소를 출현횟수만큼 반복하여 조합해서 복구한다.

텍스트에서 단어의 출현횟수 세기

아래 예제는 특정한 텍스트에서 해당 텍스트를 구성하는 모든 단어와, 그 단어의 출현 빈도를 세는 코드이다.  총 세 가지로 접근한다.

  1.  첫 번째 코드는 순수하게 사전만 사용한다. {단어:출현횟수} 로 구성되는 사전에 단어가 있으면 횟수를 +1하고 없으면 값이 1이 되도록 키를 추가한다.  이 비교의 과정은 setdefault() 메소드를 사용해서 간결하게 코딩했다.
  2. 두 번째 코드는 defaultdict 타입을 사용하는 것이다. 이 타입은 디폴트 값을 생성하는 함수를 설치하여 없는 키가 조회되면 자동으로 디폴트값을 갖도록 한다. 그럼에도 코드수는 1의 예제와 크게 다르지 않다.
  3. 세 번째 코드는 Counter 를 사용했다. 그리고 import 구문을 제외하면 1줄이다.
def occurrences_of_words(txt):
  result = dict()
  for word in txt.split():
    result[word] = result.setdefault(word, 0) + 1
  return result

## defaultdict 
from collections import defaultdict

def occ_2(txt):
  result = defaultdict(int)
  for word in txt.split():
    result[word] += 1
  result result


## using Counter
from collections import Counter
occ_map = Counter(txt.split())

현재 사용하고 있는 파이썬 버전은 3.6.1인데, 이 버전에서의 Counter(iterable).items()를 호출하면 공교롭게도 OrderedDict 마냥, 키의 순서가 입력된 순서와 일치한다. (100만 단위 길이의 문자열로 테스트해봤을 때에도 순서 일치 조건이 성립했다!) 아직 이와 관련된 공식적인 아티클을 발견하지는 못했는데, 어떤 케이스에서 성립하는지 아시는 분은 댓글로 제보주시면 감사하겠다.

 

가장 많이 출현한 키 찾기

most_common(n)을 사용하면 가장 많이 출현한 키를 n개 까지 찾아준다. 이 때, 공동 x위가 있는 경우에도 n개 만큼 잘리니 주의해야 한다. 이때의 리턴값은 (키, 카운트)의 튜플의 리스트이며, n을 생략하면 전체 키에 대해서 빈도순으로 정렬하여 출력한다.

그외의 메소드

subtract는 두 개의 카운터 인스턴스 사이의 뺄셈을 수행한다. 마치 dict.update()와 유사한데, 값을 업데이트하는 게 아니라 카운트 값을 뺀다.  Counter.update() 메소드 역시 존재한다. 이는 반대로 두 카운터 사이의 공통키에 대해서 값을 업데이트하지 않고 더해주는 것에 주의하자. 그리고 elements() 는 각 키 * 카운트값 한 것과 같이 키와 빈도수를 이용해서 전체 표본 데이터를 재생성한다.