Вы открываете файл с данными и видите, что у одного и того же идентификатора несколько раз записаны баллы. Первая мысль: «Ошибка выгрузки, нужно удалить повторы». Но не все совпадения значений — это технические дубликаты. Часть может оказаться повторными визитами одного участника, а часть — конфликтом, когда в один и тот же визит записаны разные результаты. Условный учебный пример на шести строках покажет, как различить три ситуации и что с ними делать.

Все ID, баллы и обстоятельства выгрузки далее вымышлены. Сырой файл из шести строк сохраняется неизменным; исключение r2 относится только к отдельной рабочей версии.

Исходные данные: шесть строк и повторяющиеся ID

Представьте, что у вас есть таблица с результатами тестирования. У неё технический номер строки (row), идентификатор участника (id), номер визита (visit) и балл (score). Поле row — это служебный номер происхождения записи, он не участвует в бизнес-сравнении.

Строка   Запись
r1   A01, визит 1, балл 10
r2   A01, визит 1, балл 10
r3   A01, визит 2, балл 12
r4   A02, визит 1, балл 9
r5   A02, визит 1, балл 11
r6   A03, визит 1, балл 8
Учебная схема: подтверждённая копия, другой визит и конфликт одинакового ключа требуют разных решений; шесть исходных и пять рабочих строк.
Учебная схема, данные вымышлены. Подтверждение технической копии r2 — условие примера; одинаковые значения сами по себе не обосновывают удаление.

Первый шаг: выбираем поля для сравнения

Прежде чем искать дубликаты, решите, какие столбцы входят в бизнес-сравнение. В этом примере row не входит. Если оставить row в проверке, все шесть строк окажутся уникальными, потому что у каждой свой технический номер.

Метод pandas DataFrame.duplicated() как раз позволяет ограничить сравнение нужными полями с помощью параметра subset. По умолчанию он смотрит все столбцы, что в учебном файле дало бы False для каждой строки — бесполезно. keep=False помечает True все строки, входящие в повторяющуюся группу, а не только повтор после первого вхождения.

Три маски совпадения

Маска 1: поля id, visit, score

Сравнение по трём полям ищет полные дубликаты — строки, где совпало всё: участник, визит и балл. Результат:

Строка   Совпадение
r1    True
r2    True
r3    False
r4    False
r5    False
r6    False

По трём выбранным полям совпадают r1 и r2. Само совпадение ещё не объясняет происхождение записей и не даёт основания удалить одну из них.

Маска 2: поля id, visit

Если убрать из сравнения score, мы увидим пары с одинаковым участником и номером визита, независимо от балла:

Строка   Совпадение
r1    True
r2    True
r3    False
r4    True
r5    True
r6    False

Здесь r4 и r5 — участник A02, оба в первый визит, но с разными баллами (9 и 11). Для pandas это дубликат по выбранным полям. Но для задач исследования это не дубликат, а конфликт.

Маска 3: одно поле id

Сравнение только по id покажет всех, кто встречается более одного раза, независимо от визитов и баллов:

Строка   Совпадение
r1    True
r2    True
r3    True
r4    True
r5    True
r6    False

Пять строк из шести отмечены — слишком грубо для бизнес-решения. Эта маска помогает найти повторяющиеся ID, но не различает визиты, копии и конфликты. В ней A03 встречается один раз, а A01 и A02 требуют проверки по другим полям.

Журнал решений: три разных основания

Строка   Решение
r1    оставляем как первую запись визита
r2    удаляем — это техническая копия r1 при повторной выгрузке (подтверждено документацией учебного примера)
r3    оставляем — это другой визит участника A01
r4    оставляем — причина расхождения баллов не известна, помечаем флагом review
r5    оставляем — та же пара id+visit, флаг review
r6    оставляем — единственная запись A03

Итоговая рабочая версия: пять строк

После исключения технической копии r2 в рабочей таблице остаётся пять строк. В них три различных идентификатора (A01, A02, A03) и четыре различных пары id+visit (A01/1, A01/2, A02/1, A03/1). Пара A02/1 представлена двумя строками (r4, r5) с разными баллами — это неразрешённый конфликт, и обе строки сохранены с пометкой review.

Строка   Запись
r1    A01, visit 1, score 10 (оставлена)
r3    A01, visit 2, score 12 (оставлена)
r4    A02, visit 1, score 9 (оставлена, review)
r5    A02, visit 1, score 11 (оставлена, review)
r6    A03, visit 1, score 8 (оставлена)

Пять строк не означают пять уникальных участников: в рабочей версии три ID. Не следует также считать каждую строку отдельным подтверждённым наблюдением: ключ A02/1 представлен двумя строками с разными баллами. Его статус остаётся неразрешённым; эти оценки не включают в анализ до уточнения источника.

Чего не делать с конфликтной парой

Когда мы не знаем, почему в одном визите два разных балла, нельзя выбирать последнее значение, максимальное, минимальное или среднее арифметическое. Любое из этих действий — не очистка данных, а подмена реальности собственным предположением. В этом учебном примере обе строки сохраняют с флагом review и уточняют источник. Для реального набора решение принимают по его протоколу и документированным основаниям.

Почему техническая копия не определяется автоматически

В учебном примере дополнительное условие гласит: r2 — техническая копия r1, возникшая при повторной выгрузке. Но pandas не знает этого — он видит только одинаковые числа. Поэтому решение об удалении принимает человек, опираясь на документацию процесса: например, на журнал выгрузок. Если бы такой пометки не было, r1 и r2 остались бы неразличимы. Учебные данные подготовлены 27.10.2026.

Главное

  • Не включайте технический номер строки в бизнес-сравнение.
  • Явно выбирайте поля для subset в duplicated(): результат зависит от того, на какой вопрос отвечает сравнение.
  • Три различных набора полей дают три разных ответа: полные дубликаты, пары id+visit и всех участников с повтором.
  • Техническую копию от повторного визита отличает не алгоритм, а внешняя документация.
  • Неразрешённый конфликт (одинаковые id+visit, разные score) не подлежит автоматическому сглаживанию — сохраняйте обе строки и ставьте пометку.

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

Источники