본문 바로가기
Study/Python

Python collections의 Counter로 개수 세기

by 개발새-발 2021. 5. 27.
반응형

Python의 리스트나 튜플 혹은 이외의 iterable 한 객체에서 안에 요소가 몇 개가 들어있는지 셈을 하고 싶을 때가 있다. 구현이 오래 걸리는 작업은 아니지만, 구현하기 귀찮거나 시간이 없을 때 collections의 Counter를 사용해주면 좋다. 이 글은 Counter를 사용하는 방법에 대한 내용을 담고 있다.

 

Counter import

Counter를 사용해주기 위해 먼저 import를 하자.

from collections import Counter

 

기본적인 Counter의 생성 및 사용

생성자에 아무 값도 넣어주지 않으면 빈 Counter가 생성된다.

cnt = Counter()
print(cnt)
Counter()

 

Counter를 사용하여 iterable 한 객체가 담고 있는 것들을 세보자.

words = ['apple','apple','banana','cherry','cherry','cherry']
cnt = Counter(words)
print(cnt)
Counter({'cherry': 3, 'apple': 2, 'banana': 1})

words에서 단어의 개수를 잘 세주었다.

cnt = Counter("aabbbccccdddddd")
print(cnt)
Counter({'d': 6, 'c': 4, 'b': 3, 'a': 2})

문자열에서 각 문자의 개수를 잘 세주었다.

 

dictionary를 이용해서 Counter를 설정해 줄 수도 있다.

word_dict = {
        'apple':4,
        'banana':9,
        'cherry':3
}
cnt = Counter(word_dict)
print(cnt)
Counter({'banana': 9, 'apple': 4, 'cherry': 3})

 

생성자에서 keyword arg로도 초기값 설정이 가능하다.

cnt = Counter(apple=3,banana=2,cherry=8)
print(cnt)
Counter({'cherry': 8, 'apple': 3, 'banana': 2})

 

Counter를 만들고 이후에 값을 지정하는 것도 가능하다.

cnt = Counter()
cnt['apple'] = 1
cnt['banana'] = 5
cnt['cherry'] = 2
print(cnt)
Counter({'cherry': 8, 'apple': 3, 'banana': 2})

 

Counter에서 어떤 항목이 몇 번 세어졌는지 확인해보자. 위에서 사용한 words를 이용하여 다시 Counter를 만들어 보았다.

cnt = Counter(words)
print(cnt['apple'])
print(cnt['durian'])
2
0

words'durian'은 존재하지 않았었다. Counter에 존재하지 않는 key로 값을 불러오려고 할 때, KeyError가 아닌 0을 받는다.

 

update, subtract

update는 주어진 iterable에서 센 결과나 주어진 dictionary의 값을 카운터에 더해준다. subtractupdate와 반대로 카운터에서 빼준다. 이때, 0 이하의 값이 만들어질 수 있다.

cnt = Counter('aabbbbccc')
print(cnt)
cnt.update('aabc')
print(cnt)
cnt.subtract('abcccccc')
print(cnt)
Counter({'b': 4, 'c': 3, 'a': 2})
Counter({'b': 5, 'a': 4, 'c': 4})
Counter({'b': 4, 'a': 3, 'c': -2})
cnt = Counter({'a':2,'b':4,'c':3})
print(cnt)
cnt.update({'a':2,'b':1,'c':1})
print(cnt)
cnt.subtract({'a':1,'b':1,'c':6})
print(cnt)
Counter({'b': 4, 'c': 3, 'a': 2})
Counter({'b': 5, 'a': 4, 'c': 4})
Counter({'b': 4, 'a': 3, 'c': -2})

 

+, -,  &, | (덧셈, 뺄셈, AND, OR) 연산자와 Counter

Counter+, -, &, | 연산자의 사용이 가능하다. 이 연산들을 한 후 결과물에는 0 이하의 값을 가진 key들은 없어진다는 것에 주의하자. 아래 두 카운터 cnt1, cnt2에 대해서 연산을 수행해본다.

cnt1 = Counter(a=2,b=4,c=1,e=-4)
cnt2 = Counter(a=1,b=6,d=9)

 

+ (덧셈) 연산

두 카운터의 값들을 더해준다.

result = cnt1 + cnt2
print(result)
Counter({'b': 10, 'd': 9, 'a': 3, 'c': 1})

 

- (뺄셈) 연산

두 카운터의 값들을 빼준다.

result = cnt1 - cnt2
print(result)
Counter({'a': 1, 'c': 1})

 

& (AND) 연산

연산의 결과는 두 카운터에 동시에 존재하면서, 더 작은 값을 반영한다.

result = cnt1 & cnt2
print(result)
Counter({'b': 4, 'a': 1})

 

| (OR) 연산

연산의 결과는 두 카운터에 존재하는 모든 값을 반영하며, 두 카운터에 동시에 있는 값은 더 큰 값이 반영된다.

result = cnt1 | cnt2
print(result)
Counter({'d': 9, 'b': 6, 'a': 2, 'c': 1})

 

Unary +, -

Counter와 함께 단항 연산자를 사용할 수 있는데, 이때에도 0 이하의 값을 가진 키들은 없어진다.

print(+cnt1)
print(-cnt1)
Counter({'b': 4, 'a': 2, 'c': 1})
Counter({'e': 4})

 

most_common

Counter에서 value값을 기준으로 큰 항목부터 내림차순으로 보여준다. most_common에 아무 값도 넣어주지 않으면 모든 항목을 보여준다. 양의 정수 n을 넣어주면, 가장 큰 n개의 값을 보여준다.

cnt = Counter('someday you will find me caught beneath the landside')
print(cnt.most_common(5))
[(' ', 8), ('e', 6), ('d', 4), ('a', 4), ('i', 3)]

 

elements

key를 value만큼 반복한다.

cnt = Counter(a=3,b=2,c=4)
print(cnt.elements())
print(list(cnt.elements()))
<itertools.chain object at 0x7f0c711db470>
['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'c']
반응형

댓글