Pandas & NumPy Academy · Урок

melt: из широкого формата в длинный

Преобразуйте DataFrame из широкого формата в длинный с помощью pd.melt, указывая id_vars и value_vars.

Урок 2 из 413 шагов

«melt: из широкого формата в длинный» — бесплатный урок Pandas & NumPy Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Pandas & NumPy Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Pandas & NumPy Academy содержит 4 уроков всего.

Широкий и длинный форматы данных

Данные могут иметь две основные формы. В широком формате для каждого объекта предназначена одна строка, а измерения распределены по нескольким столбцам — например, отдельные столбцы для продаж в январе, феврале и марте. В длинном формате для каждого наблюдения предназначена одна строка, один столбец содержит имя переменной, а другой — её значение. Большинство функций анализа Pandas, библиотек машинного обучения и инструментов визуализации предпочитают длинный формат, поэтому melt() — важнейший инструмент преобразования.

Функция pd.melt()

pd.melt(df) (также доступная как df.melt()) преобразует широкий DataFrame в длинный формат. Основные параметры: id_vars (столбцы, которые нужно сохранить как неизменяемые идентификаторы), value_vars (столбцы, которые нужно преобразовать в строки), var_name (имя нового столбца переменной) и value_name (имя нового столбца значения).

import pandas as pd

# Wide format: separate columns per month
df_wide = pd.DataFrame({
    'product': ['A', 'B'],
    'Jan':     [100, 150],
    'Feb':     [120, 130],
    'Mar':     [140, 160]
})

print(df_wide)
#   product  Jan  Feb  Mar
# 0       A  100  120  140
# 1       B  150  130  160

Базовый вызов melt()

Вызовите melt(), задав в id_vars столбцы, которые нужно сохранить как идентификаторы. Каждый другой столбец преобразуется в строки: его имя становится значением нового столбца переменной, а значения его ячеек перемещаются в столбец значений. Число строк результата равно числу входных строк, умноженному на число преобразуемых столбцов значений.

df_long = df_wide.melt(
    id_vars='product',
    var_name='month',
    value_name='sales'
)
print(df_long)
#   product month  sales
# 0       A   Jan    100
# 1       B   Jan    150
# 2       A   Feb    120
# 3       B   Feb    130
# 4       A   Mar    140
# 5       B   Mar    160

Выбор столбцов для преобразования

По умолчанию преобразуются все столбцы, не перечисленные в id_vars. Используйте value_vars, чтобы преобразовать только подмножество столбцов. Столбцы, не указанные ни в id_vars, ни в value_vars, исключаются из результата. Это полезно, когда широкий DataFrame содержит как столбцы временного ряда, так и другие атрибуты, которые не нужно преобразовывать.

df_wide2 = pd.DataFrame({
    'product': ['A', 'B'],
    'category': ['Electronics', 'Clothing'],
    'Jan': [100, 150],
    'Feb': [120, 130],
    'Mar': [140, 160]
})

# Melt only Jan and Feb, keep product and category
df_long2 = df_wide2.melt(
    id_vars=['product', 'category'],
    value_vars=['Jan', 'Feb'],
    var_name='month',
    value_name='sales'
)
print(df_long2)

Сброс индекса после melt()

melt() сохраняет исходные индексы строк, повторяя их для каждой переменной. Поэтому результат часто имеет непоследовательный индекс, например [0, 1, 0, 1, 0, 1]. Рекомендуется сразу после melt() вызвать reset_index(drop=True), чтобы получить в результате чистый последовательный индекс от 0 до n-1.

df_long = df_wide.melt(id_vars='product', var_name='month', value_name='sales')
print('Before reset:', df_long.index.tolist())
# [0, 1, 0, 1, 0, 1]

df_long = df_long.reset_index(drop=True)
print('After reset:', df_long.index.tolist())
# [0, 1, 2, 3, 4, 5]

melt() — обратная операция к pivot()

Концептуально melt() является обратной операцией к pivot() / pivot_table(). С помощью pivot_table() можно перейти от длинного формата к широкому, а с помощью melt() — обратно от широкого к длинному. Такой переход туда и обратно часто используется в конвейерах обработки: получить данные в широком формате, преобразовать их в длинный формат для построения графиков в Seaborn или создания признаков для машинного обучения, а затем при необходимости снова преобразовать в широкую форму для отчётной таблицы.

# long -> wide
table = df_long.pivot_table(values='sales', index='product',
                            columns='month', aggfunc='sum')
print(table)
# product  Feb  Jan  Mar
# A        120  100  140
# B        130  150  160

# wide -> long again
long_again = table.reset_index().melt(id_vars='product', var_name='month', value_name='sales')
print(long_again.head())

Использование melt() для построения графиков в Seaborn

Категориальные графики и графики отношений Seaborn лучше всего работают с данными в длинном формате. Типичный рабочий процесс: начать с широкого DataFrame, содержащего отдельный столбец для каждой группы, преобразовать его в длинный формат, чтобы один столбец определял группу, а другой содержал значения, а затем передать оба столбца в параметры hue и x/y Seaborn. Это одна из самых распространённых причин использовать melt().

import seaborn as sns
import matplotlib.pyplot as plt

# Long format is required for sns.lineplot with hue
df_long = df_wide.melt(id_vars='product', var_name='month', value_name='sales')

# sns.lineplot(data=df_long, x='month', y='sales', hue='product')
# plt.show()
print('Long data ready for Seaborn:')
print(df_long)

Именование выходных столбцов

По умолчанию melt() называет новый столбец переменной 'variable', а столбец значений — 'value'. Всегда заменяйте эти имена на содержательные с помощью var_name и value_name. Описательные имена столбцов упрощают чтение последующего кода и предотвращают путаницу, когда DataFrame содержит десятки столбцов.

# Default: generic column names 'variable' and 'value'
default = df_wide.melt(id_vars='product')
print(default.columns.tolist())
# ['product', 'variable', 'value']

# Better: descriptive names
good = df_wide.melt(id_vars='product', var_name='month', value_name='revenue_usd')
print(good.columns.tolist())
# ['product', 'month', 'revenue_usd']

Преобразование данных опроса

Классический вариант использования melt() — ответы на опрос, где каждый столбец соответствует вопросу, а каждая строка — респонденту. Преобразование переводит широкую форму в длинную, создавая столбцы для идентификатора респондента, названия вопроса и значения ответа. После этого можно легко вычислить распределение ответов для каждого вопроса с помощью groupby().

survey = pd.DataFrame({
    'respondent': [1, 2, 3],
    'Q1_rating': [5, 3, 4],
    'Q2_rating': [4, 5, 3],
    'Q3_rating': [2, 4, 5]
})

long = survey.melt(id_vars='respondent', var_name='question', value_name='rating')
print(long)
print(long.groupby('question')['rating'].mean())

Сортировка преобразованного результата

После преобразования строки упорядочены по исходному порядку столбцов (для каждой строки: Jan, Feb, Mar). Часто требуется сначала отсортировать их по столбцу идентификатора, а затем по столбцу переменной. Используйте sort_values() для преобразованного DataFrame, чтобы получить порядок, наиболее подходящий для Вашего анализа или последующей обработки.

df_long = df_wide.melt(id_vars='product', var_name='month', value_name='sales')

# Sort by product, then month
df_sorted = df_long.sort_values(['product', 'month']).reset_index(drop=True)
print(df_sorted)
#   product month  sales
# 0       A   Feb    120
# 1       A   Jan    100
# 2       A   Mar    140
# 3       B   Feb    130
# 4       B   Jan    150
# 5       B   Mar    160

melt() в конвейере обработки данных

В типичном конвейере обработки данных melt() используется сразу после загрузки или очистки данных в широком формате, до этапа анализа или моделирования. Разместите его в начале конвейера, чтобы быстро перейти к длинному формату, после чего все последующие операции (groupby, Seaborn, библиотека машинного обучения) смогут работать с чистыми данными в длинном формате без специальных исключений.

def load_and_reshape(filepath):
    raw = pd.read_csv(filepath)
    # Melt all month columns into long format
    month_cols = [c for c in raw.columns if c.startswith('month_')]
    long = raw.melt(
        id_vars=[c for c in raw.columns if c not in month_cols],
        value_vars=month_cols,
        var_name='month',
        value_name='value'
    )
    return long.reset_index(drop=True)

Быстрая проверка

Проверьте, насколько хорошо Вы поняли преобразование данных из широкого формата в длинный с помощью pd.melt из этого урока.

Итоги урока

В этом уроке Вы узнали, что melt() преобразует широкий формат в длинный, превращая столбцы в строки; id_vars указывает, какие столбцы остаются неизменными, а value_vars выбирает столбцы для преобразования; var_name и value_name задают описательные имена новым столбцам; а длинный формат предпочтителен для Seaborn, groupby и конвейеров машинного обучения. Далее мы рассмотрим stack и unstack для изменения формы DataFrames с MultiIndex.

Можно начать бесплатно

Изучай Python с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
30
Уроки
120

Часто задаваемые вопросы

Урок «melt: из широкого формата в длинный» бесплатный?

Да — полный текст урока «melt: из широкого формата в длинный» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Pandas & NumPy Academy, подпишись на CoddyKit PRO. Курс Pandas & NumPy Academy содержит 4 уроков всего.

Чему я научусь в уроке «melt: из широкого формата в длинный»?

Преобразуйте DataFrame из широкого формата в длинный с помощью pd.melt, указывая id_vars и value_vars. Ты практикуешь Pandas & NumPy Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Pandas & NumPy Academy?

Предыдущий опыт не требуется. Pandas & NumPy Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «melt: из широкого формата в длинный»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Pandas & NumPy Academy?

Да. Каждый урок Pandas & NumPy Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. pivot_table: перекрёстная таблица
  2. melt: из широкого формата в длинный
  3. stack и unstack с MultiIndex
  4. crosstab для таблиц частот
← Назад к Pandas & NumPy Academy