이 튜토리얼에서는 파이썬의 collections 모듈에 포함된 Counter 객체를 활용하는 방법을 자세히 알아봅니다.
파이썬에서 긴 시퀀스(예: 리스트나 문자열)를 다룰 때, 시퀀스 내 각 항목의 등장 횟수를 저장해야 할 경우가 종종 있습니다.
파이썬 딕셔너리는 이러한 목적에 적합한 내장 데이터 구조이지만, collections 모듈의 Counter 클래스는 카운터 생성을 간소화하여 작업을 보다 효율적으로 만들어줍니다. Counter는 시퀀스 내 항목과 해당 개수를 저장하는 딕셔너리입니다.
앞으로 몇 분 동안 다음 내용을 살펴볼 것입니다.
- 파이썬 Counter 객체의 활용 방법
- 반복 가능한 데이터(iterable) 내 항목의 개수를 저장하는 파이썬 딕셔너리 생성 방법
- 단순화된 구문을 사용하여 파이썬 Counter로 딕셔너리를 재구성하는 방법
- 요소 업데이트, 빼기, 두 Counter 객체 간의 교집합 찾기 등의 작업 수행
- most_common() 메서드를 사용하여 Counter에서 가장 빈번하게 나타나는 항목을 추출하는 방법
시작해 보겠습니다!
파이썬 컬렉션 모듈과 Counter 클래스
파이썬에서는 항목과 그 개수를 저장하기 위해 딕셔너리를 자주 사용합니다. 여기서 항목은 키, 개수는 값으로 저장됩니다.
Counter 클래스는 파이썬 내장 컬렉션 모듈에 포함되어 있으므로, 다음과 같이 파이썬 스크립트에서 임포트하여 사용할 수 있습니다.
from collections import Counter
Counter 클래스를 임포트한 후에는 다음과 같이 Counter 객체를 인스턴스화할 수 있습니다.
<counter_object> = Counter(iterable)
여기서:
- iterable은 파이썬 리스트, 문자열, 튜플 등 유효한 파이썬 반복 가능한 데이터입니다.
- iterable의 항목은 해시 가능해야 합니다.
이제 Counter를 사용하여 파이썬 반복 가능한 데이터로부터 Counter 객체를 생성하는 방법을 알았으니, 코딩을 시작해 봅시다.
본 튜토리얼에서 사용된 예제는 이 GitHub gist에서 찾을 수 있습니다.
파이썬 반복 가능한 데이터로부터 Counter 객체 생성하기
예를 들어, ‘renaissance’라는 파이썬 문자열을 만들고 이를 `word` 변수에 할당해 보겠습니다.
>>> word = "renaissance"
우리의 목표는 `word` 문자열의 각 문자가 해당 문자열에서 나타나는 횟수에 매핑되는 딕셔너리를 생성하는 것입니다. 한 가지 방법은 다음과 같이 for 루프를 사용하는 것입니다.
>>> letter_count = {} >>> for letter in word: ... if letter not in letter_count: ... letter_count[letter] = 0 ... letter_count[letter] += 1 ... >>> letter_count {'r': 1, 'e': 2, 'n': 2, 'a': 2, 'i': 1, 's': 2, 'c': 1}
위 코드 조각이 수행하는 작업을 분석해 보겠습니다.
- `letter_count`를 빈 파이썬 딕셔너리로 초기화합니다.
- `word` 문자열을 순회합니다.
- `letter_count` 딕셔너리에 현재 문자가 존재하는지 확인합니다.
- 만약 문자가 없으면 값을 0으로 하여 추가하고, 그 다음 값을 1 증가시킵니다.
- `word`에서 문자가 나타날 때마다 해당 문자에 대한 값이 1씩 증가합니다.
- 이 과정은 문자열 전체를 순회할 때까지 계속됩니다.
for 루프를 사용하여 문자열 `word`를 순회함으로써 `letter_count` 딕셔너리를 직접 만들었습니다.
이제 collections 모듈의 Counter 클래스를 사용해 보겠습니다. 반복문을 사용하는 대신, `Counter()`에 문자열 `word`를 전달하기만 하면 `letter_count`를 얻을 수 있습니다.
>>> from collections import Counter >>> letter_count = Counter(word) >>> letter_count Counter({'e': 2, 'n': 2, 'a': 2, 's': 2, 'r': 1, 'i': 1, 'c': 1})
Counter 객체는 파이썬 딕셔너리이기도 합니다. 내장 함수 `isinstance()`를 사용하여 이를 확인할 수 있습니다.
>>> isinstance(letter_count,dict) True
보시다시피 `isinstance(letter_count, dict)`는 Counter 객체 `letter_count`가 파이썬 `dict` 클래스의 인스턴스임을 나타내는 `True`를 반환합니다.
Counter 객체 수정
지금까지 파이썬 문자열로부터 Counter 객체를 생성하는 방법을 배웠습니다.
Counter 객체를 수정하려면, 다른 반복 가능한 데이터의 요소로 업데이트하거나, 다른 반복 가능한 데이터를 빼서 수정할 수도 있습니다.
다른 반복 가능한 데이터의 요소로 Counter 업데이트
다른 문자열 `another_word`를 초기화해 보겠습니다.
>>> another_word = "effervescence"
`another_word` 문자열의 항목으로 `letter_count` Counter 객체를 업데이트하고 싶다고 가정해 봅시다.
Counter 객체 `letter_count`에 대해 `update()` 메서드를 사용할 수 있습니다.
>>> letter_count.update(another_word) >>> letter_count Counter({'e': 7, 'n': 3, 's': 3, 'c': 3, 'r': 2, 'a': 2, 'f': 2, 'i': 1, 'v': 1})
결과에서 Counter 객체가 `another_word`의 문자와 해당 개수를 포함하도록 업데이트되었음을 확인할 수 있습니다.
다른 반복 가능한 데이터에서 요소 빼기
이제 `letter_count` 객체에서 `another_word`의 값을 빼 보겠습니다. 이를 위해 `subtract()` 메서드를 사용할 수 있습니다. `
`letter_count`에서 `another_word`를 빼 봅시다.
>>> letter_count.subtract(another_word) >>> letter_count Counter({'e': 2, 'n': 2, 'a': 2, 's': 2, 'r': 1, 'i': 1, 'c': 1, 'f': 0, 'v': 0})
`another_word`의 문자에 해당하는 값이 감소했지만, 추가된 ‘f’와 ‘v’ 키는 제거되지 않았음을 알 수 있습니다. 이제 해당 값은 0으로 매핑됩니다.
참고: 여기서는 파이썬 문자열인 `another_word`를 `subtract()` 메서드 호출에 전달했습니다. 파이썬 Counter 객체나 다른 반복 가능한 데이터를 전달할 수도 있습니다.
파이썬에서 두 Counter 객체 사이의 교집합
때로는 두 파이썬 Counter 객체 간의 교집합을 찾아, 둘 사이에 어떤 키가 공통적으로 존재하는지 확인할 필요가 있습니다.
문자열 `another_word`인 ‘effervescence’로부터 Counter 객체, 예를 들어 `letter_count_2`를 만들어 보겠습니다.
>>> another_word = "effervescence" >>> letter_count_2 = Counter(another_word) >>> letter_count_2 Counter({'e': 5, 'f': 2, 'c': 2, 'r': 1, 'v': 1, 's': 1, 'n': 1})
간단한 & 연산자를 사용하여 `letter_count`와 `letter_count_2` 사이의 교집합을 찾을 수 있습니다.
>>> letter_count & letter_count_2 Counter({'e': 2, 'r': 1, 'n': 1, 's': 1, 'c': 1})
두 단어에 공통된 키와 그 등장 횟수를 얻는 방법에 주목하십시오. ‘renaissance’와 ‘effervescence’ 모두 ‘e’가 두 번, ‘r’, ‘n’, ‘s’, ‘c’가 각각 한 번씩 공통적으로 나타납니다.
most_common을 사용하여 가장 빈번한 항목 찾기
파이썬 Counter 객체에 대해 수행되는 또 다른 일반적인 작업은 가장 자주 발생하는 항목을 찾는 것입니다.
Counter에서 상위 k개의 가장 일반적인 항목을 얻으려면 Counter 객체에서 `most_common()` 메서드를 사용할 수 있습니다. 여기에서는 `letter_count`에서 `most_common()`을 호출하여 가장 자주 발생하는 3개의 문자를 찾습니다.
>>> letter_count.most_common(3) [('e', 2), ('n', 2), ('a', 2)]
‘renaissance’라는 단어에서 ‘e’, ‘n’, ‘a’ 문자가 두 번씩 나타나는 것을 확인할 수 있습니다.
이는 Counter에 많은 항목이 포함되어 있고 가장 일반적인 키로 작업해야 할 때 특히 유용합니다.
결론
다음은 튜토리얼에서 배운 내용에 대한 간략한 요약입니다.
- 파이썬 내장 collections 모듈의 Counter 클래스를 사용하여 모든 반복 가능한 데이터 항목의 개수 값을 담은 딕셔너리를 얻을 수 있습니다. 이터러블의 모든 항목이 해시 가능한지 확인해야 합니다.
- `counter1.update(counter2)` 구문과 함께 `update()` 메서드를 사용하면 다른 Counter 객체 또는 다른 이터러블의 내용으로 하나의 파이썬 Counter 객체의 내용을 업데이트할 수 있습니다. `counter2` 대신 이터러블을 사용할 수 있습니다.
- 업데이트된 카운터에서 이터러블 중 하나의 내용을 제거하려면 `counter1.subtract(counter2)`와 같이 `subtract()` 메서드를 사용할 수 있습니다.
- 두 Counter 객체 간에 공통된 요소를 찾으려면 `&` 연산자를 사용할 수 있습니다. 두 개의 Counter `counter1`과 `counter2`가 주어지면 `counter1 & counter2`는 이 두 Counter 객체의 교집합을 반환합니다.
- Counter에서 k개의 가장 빈번한 항목을 얻으려면 `most_common()` 메서드를 사용할 수 있습니다. `counter.most_common(k)`는 k개의 가장 일반적인 항목과 해당 개수를 제공합니다.
다음으로는 collections 모듈의 또 다른 클래스인 defaultdict를 사용하는 방법을 배우게 됩니다. 일반 파이썬 딕셔너리 대신 defaultdict를 사용하면 누락된 키를 보다 효과적으로 처리할 수 있습니다.