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

Разберём на конкретном вымышленном примере. Никакого реального исследования — только учебная ситуация, чтобы понять, что именно происходит с ячейками, почему не теряются участники и как проверить, что вы ничего не испортили.

Исходная широкая таблица (3 участника, 2 предмета)
IDматематикаистория
U16070
U28090
U350—
Учебная широкая таблица трёх ID преобразована в шесть строк id, subject, score: оценки 60,70,80,90,50 и один сохранённый пропуск.
Учебная схема, не скриншот программы. Данные вымышлены. math — математика, history — история. Число участников остаётся 3, пропуск не заменён нулём.

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

Теперь ту же информацию представим иначе: каждая пара «участник — предмет» станет отдельной строкой.

Длинная таблица (6 строк, 3 столбца)
IDsubjectscore
U1математика60
U1история70
U2математика80
U2история90
U3математика50
U3история—

Строк стало больше — шесть вместо трёх. Но участников по-прежнему трое. Просто идентификатор U1 теперь повторяется в двух строках: для математики и для истории. Уникальной в длинной таблице служит пара (ID, subject): каждая комбинация участника и предмета встречается не более одного раза. Документация pandas описывает это отличие: в «записном» или «широком» формате обычно одна строка на субъект, в «длинном» — несколько строк на один субъект там, где применимо.

Пропуск по истории для U3 перешёл в длинную таблицу как пропуск. Это важно: если вы случайно поставите туда ноль, обратное преобразование даст неверную исходную картину.

Как это выглядит в программе (объяснение без кода)

Операция перехода из широкой таблицы в длинную обычно называется melt (в pandas — pandas.melt). Вы указываете:

  • идентификатор — столбец, который остаётся неизменным (у нас ID);
  • измеряемые столбцы — те, что вы хотите «переплавить» в строки (у нас математика и история);
  • новые имена — как назвать столбец с названиями переменных (мы назвали subject) и столбец со значениями (score).

Обратная операция — pivot (в pandas — DataFrame.pivot). Вы задаёте:

  • index — столбец, который станет строками новой таблицы (у нас ID);
  • columns — столбец, значения которого образуют новые заголовки столбцов (subject);
  • values — столбец, откуда берутся числа (score).

Документация pandas прямо говорит: pivot не поддерживает агрегацию. Если для одной и той же пары (index, columns) есть несколько значений, возникает ошибка ValueError. Допустим, вы случайно продублировали в длинной таблице строку U2 по математике с другим баллом — 85. Тогда при попытке вернуть широкую таблицу программа сообщит, что не может однозначно определить, какое значение использовать: 80 или 85. И это правильно. Усреднять их автоматически без проверки и обоснованного правила нельзя.

Проверка после преобразования

Чтобы убедиться, что вы ничего не потеряли, пробегитесь по короткому чек-листу:

  • Сколько уникальных ID? В нашем примере — три: U1, U2, U3. Исходное число не изменилось.
  • Сколько уникальных значений в столбце subject? Два: математика и история. Столько же, сколько было столбцов-переменных.
  • Сколько уникальных комбинаций (ID, subject)? Ровно шесть: 3 ID × 2 предмета. Каждая комбинация встречается не чаще одного раза.
  • Сколько заполненных score? Пять (пропуск не в счёт).

После обратного преобразования (pivot) при уникальной паре (ID, subject) значения должны восстановиться в тех же комбинациях; отдельно проверьте порядок строк, названия столбцов и представление пропуска. Функция pandas.isna позволяет определить, какие значения являются пропущенными.

Проверка обратного перехода на учебном наборе

После сопоставления по ID и названиям предметов получаем те же исходные значения. Сохранены 3 ID, 5 оценок и 1 пропуск. Порядок столбцов ниже выбран как в исходной таблице.

IDматематикаистория
U16070
U28090
U350— (пропуск)

Пошаговый учебный порядок (не норматив)

  1. Сохраните исходную таблицу отдельно — например, в другой лист или файл.
  2. Выберите столбец-идентификатор. Убедитесь, что он уникально идентифицирует каждую строку исходной таблицы.
  3. Явно задайте id_vars: ID; value_vars: математика и история; var_name: subject; value_name: score. Если есть другие нужные поля, заранее определите, как их сохранить. Сам исходный файл держите отдельно, а неуказанные в этой операции поля не считайте автоматически перенесёнными.
  4. Примените melt: ID остаётся как есть, выбранные столбцы «расплавляются».
  5. Проверьте, что число строк стало равно (число строк в широкой таблице) × (число переменных). У нас 3 × 2 = 6.
  6. Для обратного преобразования: примените pivot с index=ID, columns=subject, values=score.
  7. Сравните значения по ID и названиям предметов, отдельно проверьте пропуск. Порядок строк и столбцов, а также запись числового типа могут отличаться; при необходимости восстановите исходный порядок перед сравнением.

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

Ошибки, которые стоит проверить

  • Списать пропуск за ноль. Пропуск остаётся пропуском. Если вы запишете 0, обратное преобразование даст неверную картину.
  • Повторная пара (ID, subject). Если так случилось, pivot выдаст ошибку. Не усредняйте автоматически — разберитесь, откуда взялся дубль.
  • Потерять идентификатор. Без id_vars столбец ID не будет сохранён как идентификатор. Если при этом value_vars не задан, melt по умолчанию рассматривает остальные столбцы как измеряемые. Для нашего примера явно укажите оба набора: ID и два предмета.
  • Подумать, что 6 строк = 6 участников. В длинной таблице ID повторяется — участников столько же, сколько уникальных ID.

Что почитать по теме

Назначение и аргументы операций описаны в официальной документации pandas: melt переводит выбранные столбцы в строки, pivot восстанавливает представление по ключам без агрегации. Руководство содержит дополнительные примеры преобразования. Ссылки приведены ниже; учебные значения в этой статье составлены отдельно.

Этот материал — учебный пример. Все числа и ID вымышлены, не переносите их на реальное исследование без адаптации.

Заодно посмотрите как описывать переменные и проверять данные после сбора — это пригодится, когда будете настраивать свою кодировочную книгу.

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

Источники

Фото: Mikhail Nilov / Pexels