В двух выгрузках посчитаны категории A, B и C. Нужно сохранить разность «первое количество минус второе» для каждой категории, включая увеличение и отсутствие изменения. Для такой задачи выражение first - second у Counter может убрать важные строки: в его результате остаются только положительные счётчики.

Категории и количества ниже вымышлены. Перед нами две заранее согласованные сводки одного учебного набора категорий; это не измерение эффекта и не сведения об участниках исследования. В каждой сводке полностью учтены категории A, B и C, неизвестных пропусков здесь нет. Направление разности задано явно: из первого количества вычитается второе.

Три категории с разными знаками разности

Показатель   Учебный результат
A: первое / второе / разность   3 / 1 / +2
B: первое / второе / разность   1 / 2 / −1
C: первое / второе / разность   2 / 2 / 0
Итого: первое / второе / разность   6 / 5 / +1
Авторская схема для двух вымышленных сводок Counter: суммы 6 и 5. Оператор минуса оставляет A:2 с суммой2; subtract на копии сохраняет A:2, B:−1, C:0 с суммой1. Направление — первая сводка минус вторая; это не интерфейс и не результат реального исследования.
Авторская схема для двух вымышленных сводок Counter: суммы 6 и 5. Оператор минуса оставляет A:2 с суммой2; subtract на копии сохраняет A:2, B:−1, C:0 с суммой1. Направление — первая сводка минус вторая; это не интерфейс и не результат реального исследования.

В категории A первая частота на 2 больше. В B она на 1 меньше, поэтому разность отрицательна. В C количества равны: ноль здесь рассчитанная разность, а не отсутствующее наблюдение. Сумма разностей равна 2 − 1 + 0 = 1, что сходится с 6 − 5 = 1.

В официальной документации Counter различаются арифметическая операция вычитания и метод subtract(). Операция - исключает из результата нулевые и отрицательные счётчики. Метод изменяет сам счётчик и допускает такие результаты. Поэтому для знаковой разности ниже сначала создаётся копия первой сводки.

Полный код и проверяемый вывод

from collections import Counter

first = Counter({"A": 3, "B": 1, "C": 2})
second = Counter({"A": 1, "B": 2, "C": 2})
positive_only = first - second
signed = first.copy()
signed.subtract(second)

print("first", dict(sorted(first.items())))
print("second", dict(sorted(second.items())))
print("minus", dict(sorted(positive_only.items())))
print("subtract", dict(sorted(signed.items())))
print("minus_sum", sum(positive_only.values()))
print("signed_sum", sum(signed.values()))
print("total_difference", sum(first.values()) - sum(second.values()))

Вот результат запуска этого учебного кода:

first {'A': 3, 'B': 1, 'C': 2}
second {'A': 1, 'B': 2, 'C': 2}
minus {'A': 2}
subtract {'A': 2, 'B': -1, 'C': 0}
minus_sum 2
signed_sum 1
total_difference 1

Оператор минуса дал только A со значением 2. Он не сохранил B со значением −1 и C со значением 0. После signed.subtract(second) остались все три результата. Исходный first сохранился благодаря отдельному вызову copy(); сам метод subtract() меняет объект, на котором вызван.

Почему два итога нельзя подменять друг другом

Показатель   Учебный результат
Сумма результата first - second   2; сумма только положительных разностей
Сумма signed после subtract   1; сумма знаковых разностей всех трёх категорий
Разность исходных сумм   6 − 5 = 1; совпадает со знаковой суммой

Итог 2 получается не из арифметической ошибки Python, а из другого правила отбора: оставить только положительные значения по каждой категории. Для нашей задачи нужно видеть и отрицательное изменение, и нулевую разность, поэтому выбран второй результат. Смена правила отбора меняет смысл итогового числа.

Знак нельзя толковать без направления сравнения. Здесь −1 у B означает, что в первой сводке на одну единицу меньше, чем во второй. Это не «минус один человек» в исходных данных и не доказательство ошибки наблюдения. Если поменять направление разности, изменится и знак.

Что проверить до сравнения сводок

  • Направление нужно согласовать: первая сводка минус вторая или наоборот.
  • Убедитесь, что коды категорий в обеих выгрузках означают одно и то же.
  • Отделяйте известное нулевое количество от отсутствия сведений о категории.
  • Для этой задачи используйте согласованные неотрицательные целые исходные количества.
  • Сохраните исходные сводки и отдельно запишите правило, по которому сформирован результат.

При обращении к отсутствующему ключу Counter возвращает нулевой счётчик. Это техническое поведение не доказывает, что в реальной выгрузке категорию проверили и получили нулевую частоту. Если неизвестно, охвачена ли категория, сначала уточните исходную схему, а не подставляйте ноль по умолчанию.

При подготовке таблицы полезно отдельно проверить имена столбцов до DictReader. Там Counter считает повторы заголовков; здесь задача другая — сохранить знаковые разности между двумя уже согласованными сводками. Правило сравнения и выбранный результат запишите в журнале преобразования данных.

Законченный результат упражнения

В итоге для задачи выбрана сводка A: +2, B: −1, C: 0; её сумма равна +1. Вариант, где остался только A: +2, сохранён для сравнения способов, но не выдаётся за полную знаковую разность. Сам по себе ни один из этих учебных результатов не говорит о статистической значимости или о причине различий между реальными группами.

Если следующий этап работы требует анализа собственного исследовательского набора, можно обсудить статистический анализ данных. Передайте исходные сводки и описание категорий, заранее согласовав исследовательский вопрос и объём помощи. Выбор операции над счётчиками не заменяет выбор метода анализа.