Изменение формы данных Pandas (pivot / melt / stack / unstack)

Изменение формы данных — распространённая операция в анализе данных, используемая для изменения структуры макета данных. Pandas предоставляет такие функции, как pivot, melt, stack и unstack, для преобразования между длинным и широким форматами.


pivot Сводная таблица

pivotПреобразует данные из длинного формата в широкий, аналогично функции сводной таблицы Excel.

Базовое использование

Пример

import pandas as pd

# Создать данные в длинном формате
df = pd.DataFrame({
    "Date": ["2024-01-01", "2024-01-01", "2024-01-02", "2024-01-02"],
    "Продукт": ["A", "B", "A", "B"],
    "Sales": [100, 150, 120, 90]
})

print("Данные в длинном формате:")
print(df)
print()

# Преобразовать в широкий формат
pivot_df = df.pivot(index="Date", columns="Product", values="Sales")
print("Данные в широком формате:")
print(pivot_df)

Множественный индекс

Пример

import pandas as pd

df = pd.DataFrame({
    "Year": ["2024", "2024", "2024", "2024"],
    "Quarter": ["Q1", "Q1", "Q2", "Q2"],
    "Продукт": ["A", "B", "A", "B"],
    "Sales": [100, 150, 120, 90]
})

print("Данные:")
print(df)
print()

# Сводная таблица с множественным индексом
pivot_df = df.pivot(index=["Year", "Quarter"], columns="Product", values="Sales")
print("Сводная таблица с несколькими индексами:")
print(pivot_df)

Агрегатная функция

Пример

import pandas as pd

# Случай с дублирующимися значениями
df = pd.DataFrame({
    "Date": ["2024-01-01", "2024-01-01", "2024-01-01", "2024-01-02"],
    "Продукт": ["A", "A", "B", "B"],
    "Sales": [100, 110, 80, 90]
})

print("Данные с дублирующимися значениями:")
print(df)
print()

# pivot не поддерживает дублирующиеся значения по умолчанию, нужно использовать pivot_table и указать агрегатную функцию
pivot_df = df.pivot_table(index="Date", columns="Product", values="Sales", aggfunc="sum")
print("Агрегирование с помощью sum:")
print(pivot_df)
print()

# Использовать mean
print("Агрегирование с помощью mean:")
print(df.pivot_table(index="Date", columns="Product", values="Sales", aggfunc="mean"))

pivotДублирующиеся значения не допускаются; при наличии дублирующихся значений используйтеpivot_tableи укажите агрегатную функцию.


melt: отмена сводной

meltПреобразует данные из широкого формата в длинный — операция, обратная pivot.

Пример

import pandas as pd

# Создание данных в широком формате
df = pd.DataFrame({
    "Date": ["2024-01-01", "2024-01-02"],
    "A": [100, 120],
    "B": [150, 90]
})

print("Данные в широком формате:")
print(df)
print()

# Преобразование в длинный формат
melted = df.melt(id_vars="Date", var_name="Product", value_name="Sales")
print("Данные в длинном формате:")
print(melted)

Сохранение нескольких столбцов без изменений

Пример

import pandas as pd

df = pd.DataFrame({
    "Город": ["Пекин", "Шанхай"],
    "2023 Revenue": [1000, 800],
    "2023 Profit": [200, 150],
    "2024 Revenue": [1200, 950],
    "2024 Profit": [250, 180]
})

print("Широкий формат:")
print(df)
print()

# Оставить "City" без изменений, остальные столбцы преобразовать в длинный формат
melted = df.melt(
    id_vars="City",
    var_name="Indicator",
    value_name="Value"
)
print("Длинный формат:")
print(melted)

stack и unstack

stack и unstack — функции изменения формы, предназначенные для MultiIndex.

unstack

Пример

import pandas as pd

# Создать данные с несколькими уровнями индекса
df = pd.DataFrame({
    "A": [1, 2, 3, 4],
    "B": [5, 6, 7, 8]
}, index=pd.MultiIndex.from_tuples(
    [("X", 1), ("X", 2), ("Y", 1), ("Y", 2)],
    names=["Категория", "Номер"]
))

print("Данные многоуровневого индекса:")
print(df)
print()

# unstack преобразует внутренний индекс в столбцы
print("После unstack:")
print(df.unstack())

stack

Пример

import pandas as pd

# Создать широкий формат (с индексом столбцов)
df = pd.DataFrame({
    ("A", "X"): [1, 2],
    ("A", "Y"): [3, 4],
    ("B", "X"): [5, 6],
    ("B", "Y"): [7, 8]
})

print("С многоуровневым индексом столбцов:")
print(df)
print()

# stack преобразует индекс столбцов во внутренний индекс
print("После stack:")
print(df.stack())

Практика: Преобразование бизнес-отчета

Пример

import pandas as pd

# Имитация бизнес-данных - записи о продажах
sales = pd.DataFrame({
    "Date": ["2024-01"] * 4,
    "Товар": ["Телефон", "Компьютер", "Планшет", "Наушники"],
    "Канал": ["Онлайн", "Онлайн", "Офлайн", "Онлайн"],
    "Sales Amount": [10000, 20000, 8000, 5000]
})

print("Исходные продажи:")
print(sales)
print()

# Преобразовать с помощью pivot
pivot = sales.pivot_table(
    index="Product",
    columns="Channel",
    values="Sales Amount",
    aggfunc="sum",
    fill_value=0
)
print("Сводная таблица продаж по каналам:")
print(pivot)
print()

# Преобразовать обратно в длинный формат
print("Преобразовано обратно в длинный формат:")
print(pivot.reset_index().melt(id_vars="Product", var_name="Channel", value_name="Sales Amount"))

Выбор функции изменения формы

Функция Назначение Типичный сценарий
pivot Длинный → Широкий Преобразование строк и столбцов
pivot_table Длинный → Широкий (с агрегацией) Когда есть дублирующиеся значения
melt Широкий → Длинный Приведение данных в порядок
unstack Индекс → Столбец Многоуровневый индекс
stack Столбец → Индекс Многоуровневый индекс

Цель изменения формы данных — сделать данные более подходящими для анализа или представления. Выберите подходящий метод преобразования в зависимости от требований дальнейшей обработки.

Другие расширения