Функция Pandas pd.melt()
pd.melt()является функцией верхнего уровня библиотеки Pandas, используемой дляпреобразования широкой таблицы в длинную таблицуОна «плавит» данные широкого формата, содержащие несколько столбцов, в длинный формат, аналогично операции unpivot в Excel.
Это одна из наиболее часто используемых функций при преобразовании данных, особенно полезна, когда данные нужно преобразовать в длинный формат перед визуализацией данных или когда несколько столбцов нужно объединить в один столбец.
Определение слова: meltОзначает «плавить, сплавлять»; здесь оно относится к «плавлению» структуры широкой таблицы в структуру длинной таблицы, аналогично сбору нескольких столбцов данных вместе.
Базовый синтаксис и параметры
pd.melt()является функцией верхнего уровня библиотеки Pandas, используемой для преобразования данных широкого формата в длинный формат.
Формат синтаксиса
pd.melt(frame, id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None)
Описание параметра
- Параметр:
frame- Тип: DataFrame.
- Описание:Обязательный параметр. Исходный DataFrame с данными, то есть данные, которые нужно преобразовать из широкого формата в длинный.
- Параметр:
id_vars- Тип: имя столбца, список кортежей или None.
- Описание: столбцы, используемые как идентифицирующие (ID) переменные; эти столбцы остаются неизменными после преобразования. Может быть именем одного столбца или списком имён столбцов. Если не указано, все столбцы будут рассматриваться как value_vars.
- Параметр:
value_vars- Тип: имя столбца, список кортежей или None.
- Описание: столбцы, которые нужно «расплавить», то есть какие столбцы преобразуются в строки. Если не указано, все столбцы, кроме id_vars, будут преобразованы.
- Параметр:
var_name- Тип: строка или None.
- Описание: имя нового столбца, созданного для хранения исходных имён столбцов. По умолчанию — 'variable'.
- Параметр:
value_name- Тип: string.
- Описание: Имя создаваемого столбца значений. По умолчанию — 'value'.
- Параметр:
col_level- Тип: int, str или None.
- Описание: Если столбцы являются MultiIndex, укажите уровень для преобразования.
Описание функций
- Возвращаемое значение: Возвращает DataFrame с данными, преобразованными из широкого формата в длинный формат.
- Действие: Преобразует значения нескольких столбцов в два столбца: один столбец хранит исходные имена столбцов (variable), а другой — соответствующие значения (value).
Примеры
Давайте досконально освоим с помощью серии примеров от простых к сложнымpd.melt()использование.
Пример 1: Базовое использование — преобразование простой широкой таблицы в длинную таблицу
Примеры
# 1. Создание данных в широком формате (по одному столбцу на каждый квартал)
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'Q1_sales': [100, 150, 200],
'Q2_sales': [120, 160, 210],
'Q3_sales': [130, 170, 220]
})
print("=== Исходные данные в широком формате ===")
print(df)
# 2. Использование pd.melt() для преобразования в длинный формат
melted = pd.melt(df, id_vars=['name'], value_vars=['Q1_sales', 'Q2_sales', 'Q3_sales'])
print("\n=== pd.melt() преобразовано в длинный формат ===")
print(melted)
# 3. Пользовательские имена столбцов
melted_custom = pd.melt(
df,
id_vars=['name'],
value_vars=['Q1_sales', 'Q2_sales', 'Q3_sales'],
var_name='quarter',
value_name='sales'
)
print("\n=== Пользовательские имена столбцов ===")
print(melted_custom)
Ожидаемый вывод:
=== 原始宽格式数据 ===
name Q1_sales Q2_sales Q3_sales
0 Alice 100 120 130
1 Bob 150 160 170
2 Charlie 200 210 220
=== pd.melt() 转换为长格式 ===
name variable value
0 Alice Q1_sales 100
1 Bob Q1_sales 150
2 Charlie Q1_sales 200
3 Alice Q2_sales 120
4 Bob Q2_sales 160
5 Charlie Q2_sales 210
6 Alice Q3_sales 130
7 Bob Q3_sales 170
8 Charlie Q3_sales 220
=== 自定义列名 ===
name quarter sales
0 Alice Q1_sales 100
1 Bob Q1_sales 150
2 Charlie Q1_sales 200
3 Alice Q2_sales 200
Анализ кода:
- Исходные данные представлены в широком формате, каждая строка — это человек, а Q1, Q2, Q3 — это столбцы с данными о продажах за три квартала.
id_vars=['name']Укажите столбец name, который должен остаться неизменным в качестве идентификатора.value_vars=['Q1_sales', 'Q2_sales', 'Q3_sales']Укажите столбцы, которые нужно melt.- В результате добавляется столбец variable (хранящий исходные имена столбцов) и столбец value (хранящий соответствующие значения).
- Использование
var_nameиvalue_nameможно настроить имена новых столбцов.
Пример 2: Без указания value_vars - Melt всех столбцов, кроме id_vars
Если value_vars не указан, все столбцы, кроме id_vars, автоматически подвергаются операции melt.
Примеры
# 1. Создайте данные с дополнительными столбцами
df = pd.DataFrame({
'id': [1, 2, 3],
'name': ['Alice', 'Bob', 'Charlie'],
'math': [90, 85, 92],
'english': [88, 90, 87],
'science': [95, 88, 91]
})
print("=== Исходные данные ===")
print(df)
# 2. Укажите только id_vars, все остальные столбцы автоматически подвергнутся melt
melted = pd.melt(df, id_vars=['id', 'name'])
print("\n=== Преобразовать все не-id столбцы ===")
print(melted)
# 3. Случай с несколькими id_vars
print("\n=== Несколько id_vars ===")
melted_multi = pd.melt(df, id_vars=['name'], value_vars=['math', 'english', 'science'])
print(melted_multi)
# 4. Использовать только один id_vars
print("\n=== Один id_vars ===")
melted_one = pd.melt(df, id_vars=['id'])
print(melted_one)
Ожидаемый вывод:
=== 原始数据 === id name math english science 0 1 Alice 90 88 95 1 2 Bob 85 90 88 2 3 Charlie 92 87 91 === 融化所有非id列 === id name variable value 0 1 Alice math 90 1 2 Bob math 85 2 3 Charlie math 92 3 1 Alice english 88 4 2 融化为两列(variable 和 value)。 - 不指定 value_vars 时,系统会自动识别并熔化除 id_vars 外的所有列 - id_vars 可以是单个列或多个列的组合
Анализ кода:
- Если не указано,
value_varsон автоматически выполнит meltid_varsвсе столбцы, кроме id_vars. - Когда указан только id_vars, а value_vars — нет, каждая строка данных порождает столько новых строк, сколько имеется value_vars.
- Этот метод очень удобен, когда нужно единообразно обрабатывать многоколоночные данные.
Пример 3: без id_vars - Melt всех столбцов
Если id_vars не указан, индекс исходных данных служит идентификатором.
Примеры
# 1. Создайте данные (без явного столбца id)
df = pd.DataFrame({
'Q1': [100, 150, 200],
'Q2': [120, 160, 210],
'Q3': [130, 170, 220]
})
print("=== Исходные данные ===")
print(df)
# 2. Не указывайте id_vars, используйте индекс по умолчанию
melted = pd.melt(df)
print("\n=== Без указания id_vars ===")
print(melted)
# 3. Восстановите исходный индекс
print("\n=== Сброс индекса ===")
melted_with_index = pd.melt(df, ignore_index=False)
print(melted_with_index)
# 4. Практический случай: создать идентификатор
df_with_id = pd.DataFrame({
'year': [2023, 2023, 2023],
'Q1': [100, 150, 200],
'Q2': [120, 160, 210]
})
print("\n=== Исходные данные (с year) ===")
print(df_with_id)
# Сначала добавьте year в id_vars
melted_year = pd.melt(df_with_id, id_vars=['year'])
print("\n=== Результат melt, включая year ===")
print(melted_year)
Ожидаемый вывод:
=== 原始数据 ===
Q1 Q2 Q3
0 100 120 130
1 150 160 170
2 200 210 220
=== 不指定 id_vars ===
variable value
0 Q1 100
1 Q1 150
2 融化所有列,将原始列名转为 variable 列的值,原始值转为 value 列。
Анализ кода:
- Если id_vars не указан, остаются только столбцы variable и value.
- Использование
ignore_index=Falseможет сохранить исходный индекс, что упрощает сравнение с исходными данными позже. - На практике обычно указывают один или несколько id_vars, чтобы сохранить ключевую информацию.
Пример 4: Практический случай - подготовка к визуализации данных
melt() — отличный помощник для визуализации данных; многие библиотеки для построения графиков (такие как Seaborn, Matplotlib) лучше работают с данными в длинном формате.
Примеры
# 1. Создание данных о продажах (один столбец на регион)
sales = pd.DataFrame({
'product': ['A', 'B', 'C', 'D'],
'Jan': [1200, 1500, 900, 1100],
'Feb': [1350, 1600, 950, 1200],
'Mar': [1100, 1450, 880, 1050]
})
print("=== Wide-format sales data ===")
print(sales)
# 2. Преобразование в длинный формат (для визуализации)
sales_long = pd.melt(
sales,
id_vars=['product'],
var_name='month',
value_name='sales'
)
print("\n=== Данные о продажах в длинном формате ===")
print(sales_long)
# 3. Пример обработки данных: расчёт роста год к году
# Добавить номер месяца
month_map = {'Jan': 1, 'Feb': 2, 'Mar': 3}
sales_long['month_num'] = sales_long['month'].map(month_map)
print("\n=== Добавить номер месяца ===")
print(sales_long)
# 4. Фильтрация данных за конкретный месяц
feb_sales = sales_long[sales_long['month'] == 'Feb']
print("\n=== Данные о продажах за февраль ===")
print(feb_sales)
Ожидаемый вывод:
=== 宽格式销售数据 === product Jan Feb Mar 0 A 1200 1350 1100 product Jan 180 170 6 === 长格式销售数据(用于可视化) === product month sales 0 A Jan 1200 1 B Jan 1500 2 C Jan 900 3 D Jan 1100 4 A Feb 1350
Анализ кода:
- Данные в широком формате содержат один столбец на регион/момент времени, что упрощает просмотр и ввод данных.
- Данные в длинном формате содержат одну строку на наблюдение, что является стандартным форматом для статистического анализа.
- Библиотеки визуализации, такие как Seaborn, принимают данные в длинном формате, что упрощает создание сгруппированных столбчатых диаграмм, линейных графиков и т. д.
- Использование
id_varsможет не подвергать категориальные переменные, такие как product и region, операции melt.
Пример 5: Melt с многоуровневым индексом столбцов
Когда DataFrame имеет многоуровневый индекс столбцов, можно использоватьcol_levelпараметр.
Примеры
# 1. Создание данных с многоуровневым индексом столбцов
df = pd.DataFrame(
[[100, 110, 200, 210], [150, 160, 180, 190]],
index=['Store_A', 'Store_B'],
columns=pd.MultiIndex.from_tuples([
('Электроника', 'Q1'), ('Электроника', 'Q2'),
('Мебель', 'Q1'), ('Мебель', 'Q2')
], names=['Category', 'Quarter'])
)
print("=== Исходные данные (многоуровневый индекс столбцов) ===")
print(df)
# 2. Melt всех столбцов (без указания уровня)
print("\n=== Melt all columns ===")
melted_all = pd.melt(df, ignore_index=False)
print(melted_all)
# 3. Melt только внутреннего уровня (Quarter)
print("\n=== Развернуть только уровень Quarter ===")
melted_quarter = pd.melt(df, col_level=1)
print(melted_quarter)
# 4. Развернуть внешний уровень (Category)
print(n=== Развернуть только уровень Category ===)
melted_category = pd.melt(df, col_level=0)
print(melted_category)
Ожидаемый вывод:
=== 原始数据(多层列索引)=== Category Electronics Furniture Quarter Q1 Q2 Q1 融化不同层级会产生不同的结果: - 融化内层(Quarter)保留 Category 作为 id - 融化外层(Category)保留 Quarter 作为 id
Пояснение к коду:
- Для DataFrame с многоуровневым индексом столбцов имена столбцов представлены в виде кортежа: (Category, Quarter).
col_level=0Развернуть внешний уровень (Category), сохранить Quarter как id.col_level=1Развернуть внутренний уровень (Quarter), сохранить Category как id.- Эта гибкость позволяет выбрать, какой уровень развернуть, исходя из ваших аналитических потребностей.
Другие расширенияСовет:
pd.melt()Это отличный помощник для визуализации данных. Большинство библиотек для построения графиков (например, Seaborn, Plotnine) лучше работают с данными в длинном формате; использование melt() для преобразования данных перед построением графиков — обычная практика.
Pandas: общие функции