Collections.Counter: примеры (PYTHON)

Класс Counter из модуля collections для частотного анализа данных
Раздел: Коллекции, Счетчики
collections.Counter(iterable: Iterable or mapping: Mapping = None): Counter

Функция collections.Counter

Класс Counter из модуля collections представляет собой подкласс словаря, предназначенный для подсчёта хешируемых объектов. Он часто применяется для анализа частотности элементов в последовательностях, таких как строки, списки или итерируемые объекты.

Основные случаи использования: подсчёт частоты символов в тексте, анализ вхождений элементов в коллекции, нахождение наиболее распространённых элементов, арифметические операции с мультимножествами.

Аргументы инициализации

  • iterable-or-mapping (опциональный): Может быть последовательностью (строка, список, кортеж), словарём или другим объектом с поддерживаемым интерфейсом отображения. Если аргумент не указан, создаётся пустой счётчик.

Возвращаемое значение

Экземпляр класса Counter, который наследует от dict. Ключами являются подсчитываемые элементы, значениями – их частоты (количество вхождений).

Основные методы и атрибуты

  • elements() – возвращает итератор по элементам, повторяя каждый столько раз, сколько указано в счётчике.
  • most_common([n]) – возвращает список кортежей (элемент, частота) для n наиболее часто встречающихся элементов.
  • subtract([iterable-or-mapping]) – вычитает частоты элементов из переданного итерируемого объекта или словаря.
  • Арифметические операции (+, -, &, |) поддерживаются для объединения и сравнения счётчиков.
  • При обращении к отсутствующему элементу возвращается 0, а не вызывает KeyError.

Базовые примеры использования

Создание счётчика из строки:

from collections import Counter
cnt = Counter('абракадабра')
print(cnt)
Counter({'а': 5, 'б': 2, 'р': 2, 'к': 1, 'д': 1})

Создание счётчика из списка:

words = ['яблоко', 'банан', 'яблоко', 'апельсин', 'банан', 'яблоко']
word_counts = Counter(words)
print(word_counts)
Counter({'яблоко': 3, 'банан': 2, 'апельсин': 1})

Метод most_common:

print(cnt.most_common(2))
[('а', 5), ('б', 2)]

Арифметические операции:

c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(c1 + c2)
print(c1 - c2)
Counter({'а': 4, 'б': 3})
Counter({'а': 2})

Похожие инструменты в Python

Для подсчёта элементов могут применяться альтернативные подходы.

  • Ручной подсчёт через словарь: Используется цикл и метод dict.get(). Подходит для простых сценариев, но требует больше кода и менее эффективен для сложных операций с мультимножествами.
  • Метод list.count(): Применим для поиска частоты конкретного элемента в списке. Неэффективен при необходимости подсчёта всех элементов, так как требует отдельного вызова для каждого уникального значения.
  • Pandas value_counts(): Метод для Series в библиотеке Pandas. Используется при работе с табличными данными и предоставляет расширенные возможности для анализа, но требует установки дополнительного пакета.
  • defaultdict из модуля collections: Упрощает процесс подсчёта, автоматически инициализируя отсутствующие ключи, но не предоставляет специализированных методов, таких как most_common.

Распространённые ошибки

При работе с Counter можно столкнуться с типичными проблемами.

Ожидание порядка элементов в счётчике. До Python 3.7 порядок ключей в словарях не гарантировался. Counter, будучи подклассом dict, с версии 3.7 сохраняет порядок вставки, но логически это мультимножество, где порядок не имеет семантического значения.

Использование нехешируемых элементов в качестве ключей вызывает TypeError.

from collections import Counter
try:
    cnt = Counter([[1, 2], [3, 4]])
except TypeError as e:
    print(f"Ошибка: {e}")
Ошибка: unhashable type: 'list'

Метод subtract() может создавать отрицательные счётчики, что иногда является неожиданным.

c1 = Counter(a=2)
c2 = Counter(a=5)
c1.subtract(c2)
print(c1)
Counter({'а': -3})

История изменений

Класс Counter был добавлен в Python 2.7 и Python 3.1. Существенных изменений в его публичном API не было. Однако, начиная с Python 3.7, Counter, как и все словари, гарантированно сохраняет порядок вставки элементов. В Python 3.10 были добавлены операции для работы со множествами: унарный плюс (+counter) и поддержка метода total() для вычисления суммы всех отсчетов.

# Новый метод total() в Python 3.10+
from collections import Counter
c = Counter(a=10, b=5)
print(c.total())
15

Расширенные примеры применения

Нахождение разницы между двумя текстами по частотам символов.

Пример python
text1 = "hello world"
text2 = "hello python"
c1, c2 = Counter(text1), Counter(text2)
diff = c1 - c2
print("Лишние символы в text1:", dict(diff))
print("Лишние символы в text2:", dict(c2 - c1))
Лишние символы в text1: {'w': 1, 'o': 1, 'r': 1, 'l': 1, 'd': 1}
Лишние символы в text2: {'p': 1, 'y': 1, 't': 1, 'h': 1, 'n': 1}

Подсчёт частоты слов в большом тексте с приведением к нижнему регистру и удалением знаков препинания.

Пример python
import re
from collections import Counter
text = "Привет, мир! Мир приветствует тебя. Привет!"
words = re.findall(r'\b\w+\b', text.lower())
word_counter = Counter(words)
print(word_counter.most_common())
[('привет', 2), ('мир', 2), ('приветствует', 1), ('тебя', 1)]

Имитация работы с мультимножествами: проверка, достаточно ли ингредиентов для рецепта.

Пример python
available = Counter(яйца=5, мука=500, сахар=200, молоко=1000)
recipe = Counter(яйца=3, мука=300, сахар=100, молоко=500)
# Проверка, хватает ли ингредиентов
missing = recipe - available
if not missing:
    print("Ингредиентов достаточно")
else:
    print("Не хватает:", dict(missing))
Ингредиентов достаточно

Использование elements() для восстановления последовательности.

Пример python
c = Counter({'a': 3, 'b': 1, 'c': 2})
print(sorted(c.elements()))
['a', 'a', 'a', 'b', 'c', 'c']

Операции пересечения и объединения мультимножеств.

Пример python
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print("Пересечение (минимумы):", c1 & c2)
print("Объединение (максимумы):", c1 | c2)
Пересечение (минимумы): Counter({'а': 1, 'b': 1})
Объединение (максимумы): Counter({'а': 3, 'b': 2})

Аналоги функции в других языках

В различных языках программирования существуют похожие структуры данных для подсчёта элементов.

JavaScript

Отсутствует встроенный аналог. Реализуется через объект или Map.

const arr = ['a', 'b', 'a', 'c'];
const count = {};
arr.forEach(item => count[item] = (count[item] || 0) + 1);
console.log(count);
{ a: 2, b: 1, c: 1 }

Java

Используется Map и метод merge или сторонние библиотеки, такие как Guava Multiset.

import java.util.*;
List list = Arrays.asList("a", "b", "a", "c");
Map counter = new HashMap<>();
for (String s : list) {
    counter.merge(s, 1, Integer::sum);
}
System.out.println(counter);
{a=2, b=1, c=1}

PHP

Функция array_count_values() подсчитывает частоты значений в массиве, но работает только со строками и целыми числами.

$array = ["a", "b", "a", "c"];
$result = array_count_values($array);
print_r($result);
Array ( [a] => 2 [b] => 1 [c] => 1 )

SQL

Для подсчёта частот используется агрегатная функция COUNT() вместе с GROUP BY.

SELECT item, COUNT(*) as frequency
FROM items_table
GROUP BY item;

питон collections.Counter function comments

En
Collections.Counter dict subclass for counting hashable objects