Python의 Counter를 사용하여 목록에서 각 요소의 발생 횟수 계산

사업

Python에서 내장 함수 len()을 사용하여 목록 또는 튜플의 모든 요소 수를 얻을 수 있고 count() 메서드를 사용하여 각 요소의 수(각 요소의 발생 횟수)를 얻을 수 있습니다. .

또한 Python 표준 라이브러리 컬렉션의 Counter 클래스를 사용하여 발생 횟수 순서대로 요소를 가져올 수 있습니다.

이 섹션에서는 다음을 논의할 것입니다.

  • 총 요소 수를 계산합니다.len()
  • 각 요소의 수를 계산합니다(각 요소의 발생 수):count()
  • 용법.collections.Counter
  • 요소는 발생 빈도 순으로 검색됩니다.most_common()
  • 겹치지 않는 요소(고유 요소)의 수(유형)를 센다.
  • 조건을 만족하는 요소의 수를 센다.

또한, 구체적인 예로서 다음을 샘플 코드로 설명한다.

  • 문자열에서 단어의 발생 횟수를 계산합니다.
  • 문자열에서 문자의 발생 횟수를 계산합니다.

샘플은 목록이지만 튜플을 사용하여 동일한 처리를 수행할 수 있습니다.

총 요소 수 계산: len()

목록 또는 튜플의 총 요소 수를 계산하려면 내장 함수 len()을 사용하십시오.

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']

print(len(l))
# 7

각 요소의 개수 계산(각 요소의 발생 횟수): count() 메서드

각 요소의 수(각 요소의 발생 수)를 계산하려면 목록, 튜플 등에 대해 count() 메서드를 사용합니다.

요소로 존재하지 않는 값이 인수로 전달되면 0이 반환됩니다.

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']

print(l.count('a'))
# 4

print(l.count('b'))
# 1

print(l.count('c'))
# 2

print(l.count('d'))
# 0

한 번에 각 요소의 발생 횟수를 얻으려면 다음 collection.Counter가 유용합니다.

Collections.Counter 사용 방법

Python 표준 라이브러리 컬렉션에는 Counter 클래스가 있습니다.

Counter()는 딕셔너리 유형 dict의 하위 클래스로, 요소 형태의 데이터를 키로, 발생을 값으로 가지고 있습니다.

import collections

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']

c = collections.Counter(l)
print(c)
# Counter({'a': 4, 'c': 2, 'b': 1})

print(type(c))
# <class 'collections.Counter'>

print(issubclass(type(c), dict))
# True

요소가 키로 지정되면 요소의 수를 얻을 수 있습니다. 요소로 존재하지 않는 값이 지정되면 0이 반환됩니다.

print(c['a'])
# 4

print(c['b'])
# 1

print(c['c'])
# 2

print(c['d'])
# 0

key(), values(), items() 등과 같은 사전 유형 메서드를 사용할 수도 있습니다.

print(c.keys())
# dict_keys(['a', 'b', 'c'])

print(c.values())
# dict_values([4, 1, 2])

print(c.items())
# dict_items([('a', 4), ('b', 1), ('c', 2)])

이 메서드는 dict_keys 등의 개체를 반환합니다. for 문을 실행하려는 경우 그대로 사용할 수 있습니다. 목록으로 변환하려면 list()를 사용하십시오.

출현 빈도순으로 요소 얻기: most_common() 메소드

Counter에는 발생 횟수로 정렬된 형식(요소, 발생 횟수)의 튜플 목록을 반환하는 most_common() 메서드가 있습니다.

print(c.most_common())
# [('a', 4), ('c', 2), ('b', 1)]

가장 많이 발생하는 요소는 인덱스를 지정하여 얻을 수 있습니다(예: 가장 높은 발생 횟수는 [0], 가장 낮은 횟수는 [-1]). 요소만 가져오거나 발생 횟수만 가져오려면 인덱스를 추가로 지정할 수 있습니다.

print(c.most_common()[0])
# ('a', 4)

print(c.most_common()[-1])
# ('b', 1)

print(c.most_common()[0][0])
# a

print(c.most_common()[0][1])
# 4

발생 횟수가 감소하는 순서로 정렬하려면 증분이 -1로 설정된 슬라이스를 사용합니다.

print(c.most_common()[::-1])
# [('b', 1), ('c', 2), ('a', 4)]

most_common() 메서드에 인수 n이 지정되면 가장 많이 발생하는 n개의 요소만 반환됩니다. 생략하면 모든 요소.

print(c.most_common(2))
# [('a', 4), ('c', 2)]

(요소, 발생 횟수)의 튜플이 아닌 발생 횟수로 정렬된 별도의 요소/발생 목록을 원하는 경우 다음과 같이 분해할 수 있습니다.

values, counts = zip(*c.most_common())

print(values)
# ('a', 'c', 'b')

print(counts)
# (4, 2, 1)

내장 함수 zip()은 2차원 목록(이 경우 튜플 목록)을 전치한 다음 압축을 풀고 추출하는 데 사용됩니다.

겹치지 않는 요소(고유 요소)의 수(유형)를 센다.

목록이나 튜플에 겹치지 않는 요소(고유한 요소)가 얼마나 있는지(유형이 얼마나 많은지) 계산하려면 위에서 설명한 대로 Counter 또는 set()을 사용합니다.

Counter 개체의 요소 수는 len()으로 얻을 수 있는 원래 목록의 겹치지 않는 요소 수와 같습니다.

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
c = collections.Counter(l)

print(len(c))
# 3

또한 집합 유형 집합에 대한 생성자인 set()을 사용할 수 있습니다. 이는 Counter 객체가 필요하지 않은 경우 더 쉽습니다.

집합 유형은 중복 요소가 없는 데이터 유형입니다. 목록을 set()에 전달하면 중복 값을 무시하고 고유한 값만 요소로 포함하는 집합 유형의 개체를 반환합니다. 이 유형의 요소 수는 len()으로 얻습니다.

print(set(l))
# {'a', 'c', 'b'}

print(len(set(l)))
# 3

조건을 만족하는 요소의 수를 센다.

특정 조건을 충족하는 목록 또는 튜플의 요소 수를 계산하려면 목록 이해 표기법 또는 생성기 표현식을 사용합니다.

예를 들어 다음 숫자 목록에 대해 음수 값을 가진 요소의 수를 계산합니다.

l = list(range(-5, 6))
print(l)
# [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]

목록 이해 표기법의 각 요소에 조건식을 적용하면 요소가 부울 부울(true, false)인 목록이 생성됩니다. Boolean 유형 bool은 정수 유형 int의 하위 클래스로, 여기서 true는 1로, false는 0으로 처리됩니다. 따라서 sum을 사용하여 합계를 계산하여 true 값의 개수(조건을 만족하는 요소의 개수)를 셀 수 있습니다. ().

print([i < 0 for i in l])
# [True, True, True, True, True, False, False, False, False, False, False]

print(sum([i < 0 for i in l]))
# 5

목록 이해 표기법에서 []를 ()로 바꾸면 생성기 표현식을 얻습니다. 목록 이해 표기법은 처리된 모든 요소의 목록을 생성하는 반면 생성기 표현식은 요소를 순차적으로 처리하므로 메모리 효율성이 더 높습니다.

제너레이터 표현식이 유일한 인수인 경우 ()를 생략할 수 있으므로 후자의 경우와 같이 작성할 수 있습니다.

print(sum((i < 0 for i in l)))
# 5

print(sum(i < 0 for i in l))
# 5

거짓 값의 개수(조건을 만족하지 않는 요소의 개수)를 세고 싶다면 not을 사용하세요. 참고 > 는 not보다 우선순위가 높으므로(먼저 계산됨) 다음 예에서 (i < 0)의 괄호()는 필요하지 않습니다.

print([not (i < 0) for i in l])
# [False, False, False, False, False, True, True, True, True, True, True]

print(sum(not (i < 0) for i in l))
# 6

물론 조건 자체는 변경될 수 있습니다.

print(sum(i >= 0 for i in l))
# 6

몇 가지 다른 예가 아래에 나와 있습니다.

숫자 목록의 홀수 요소 수를 가져오는 예입니다.

print([i % 2 == 1 for i in l])
# [True, False, True, False, True, False, True, False, True, False, True]

print(sum(i % 2 == 1 for i in l))
# 6

문자열 목록에 대한 조건의 예.

l = ['apple', 'orange', 'banana']

print([s.endswith('e') for s in l])
# [True, True, False]

print(sum(s.endswith('e') for s in l))
# 2

Counter는 발생 횟수를 기준으로 계산하는 데 사용됩니다. items()는 (요소, 발생 횟수)의 튜플을 검색하고 발생 횟수는 조건을 지정합니다.

다음은 2회 이상 발생한 요소를 추출하여 총 발생 횟수를 계산하는 예입니다. 이 예에는 4개의 a와 2개의 c가 있어 총 6개가 있습니다.

l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
c = collections.Counter(l)

print(c.items())
# dict_items([('a', 4), ('b', 1), ('c', 2)])

print([i for i in l if c[i] >= 2])
# ['a', 'a', 'a', 'a', 'c', 'c']

print([i[1] for i in c.items() if i[1] >= 2])
# [4, 2]

print(sum(i[1] for i in c.items() if i[1] >= 2))
# 6

다음은 2회 이상 발생하는 요소의 유형을 추출하여 발생 횟수를 세는 예이다. 이 예에는 와 c의 두 가지 유형이 있습니다.

print([i[0] for i in c.items() if i[1] >= 2])
# ['a', 'c']

print([i[1] >= 2 for i in c.items()])
# [True, False, True]

print(sum(i[1] >= 2 for i in c.items()))
# 2

문자열에서 단어의 발생 횟수를 계산합니다.

구체적인 예로 문자열에서 단어의 출현 횟수를 계산해 봅시다.

먼저, replace() 메서드를 사용하여 불필요한 쉼표와 마침표를 빈 문자열로 바꾼 다음 삭제합니다. 그런 다음 split() 메서드를 사용하여 공백으로 구분된 목록을 만듭니다.

s = 'government of the people, by the people, for the people.'

s_remove = s.replace(',', '').replace('.', '')

print(s_remove)
# government of the people by the people for the people

word_list = s_remove.split()

print(word_list)
# ['government', 'of', 'the', 'people', 'by', 'the', 'people', 'for', 'the', 'people']

목록을 만들 수 있다면 각 단어가 나타나는 횟수, 나타나는 단어의 유형, 그리고 가장 많이 나타나는 단어를 얻기 위한 collections.Counter의 most_common()을 얻을 수 있습니다.

print(word_list.count('people'))
# 3

print(len(set(word_list)))
# 6

c = collections.Counter(word_list)

print(c)
# Counter({'the': 3, 'people': 3, 'government': 1, 'of': 1, 'by': 1, 'for': 1})

print(c.most_common()[0][0])
# the

위의 과정은 매우 간단한 과정이므로 보다 복잡한 자연어 처리를 위해서는 NLTK와 같은 라이브러리를 사용하는 것이 좋습니다.

또한 일본어 텍스트의 경우 명확한 단어 분리가 없기 때문에 split()을 사용하여 텍스트를 분할할 수 없습니다. 예를 들어 Janome 라이브러리를 사용하여 이를 달성할 수 있습니다.

문자열에서 문자의 발생 횟수를 계산합니다.

문자열도 시퀀스 유형이므로 count() 메서드와 함께 사용하거나 collections.Counter()의 생성자에 인수로 전달할 수 있습니다.

s = 'supercalifragilisticexpialidocious'

print(s.count('p'))
# 2

c = collections.Counter(s)

print(c)
# Counter({'i': 7, 's': 3, 'c': 3, 'a': 3, 'l': 3, 'u': 2, 'p': 2, 'e': 2, 'r': 2, 'o': 2, 'f': 1, 'g': 1, 't': 1, 'x': 1, 'd': 1})

가장 자주 발생하는 상위 5개 문자를 검색하는 예입니다.

print(c.most_common(5))
# [('i', 7), ('s', 3), ('c', 3), ('a', 3), ('l', 3)]

values, counts = zip(*c.most_common(5))

print(values)
# ('i', 's', 'c', 'a', 'l')