- Home »

Функции melt, unmelt и pivot в Pandas — преобразование данных
Если вы работаете с серверными логами, мониторингом или обработкой данных на серверах, то рано или поздно столкнётесь с необходимостью преобразовать данные из одного формата в другой. Логи веб-сервера, метрики системы, данные из баз — всё это часто приходится перекраивать для анализа. Pandas предоставляет мощные инструменты для решения этих задач: melt()
, unmelt()
и pivot()
. Эти функции позволяют легко переводить данные из широкого формата в длинный и обратно, что критически важно для обработки серверных метрик и логов.
Сегодня разберём три ключевых вопроса: как эти функции работают под капотом, как быстро настроить их использование в ваших скриптах, и покажем практические примеры с реальными серверными данными — от простых случаев до сложных сценариев автоматизации.
Как это работает: теория в двух словах
Представьте, что у вас есть CSV с метриками сервера, где каждая строка содержит timestamp, а столбцы — это CPU, RAM, disk I/O. Это “широкий” формат. Иногда нужно преобразовать данные в “длинный” формат, где каждая метрика занимает отдельную строку. Именно для этого и нужны эти функции:
- melt() — преобразует данные из широкого формата в длинный
- pivot() — обратная операция, из длинного в широкий
- unmelt() — алиас для pivot_table(), более интуитивное название
Основная идея: данные одни и те же, но структура меняется в зависимости от задач анализа.
Быстрая настройка и базовые примеры
Установим pandas и создадим тестовые данные, похожие на серверные метрики:
import pandas as pd
import numpy as np
# Создаём тестовые данные (метрики сервера)
data = {
'timestamp': ['2024-01-01 10:00', '2024-01-01 10:01', '2024-01-01 10:02'],
'cpu_usage': [45.2, 67.8, 52.1],
'memory_usage': [78.3, 82.1, 79.9],
'disk_io': [12.5, 15.2, 11.8]
}
df = pd.DataFrame(data)
print("Исходные данные (широкий формат):")
print(df)
Melt: от широкого к длинному
Функция melt()
— это швейцарский нож для преобразования широких данных в длинные. Особенно полезна для временных рядов и метрик:
# Базовое использование melt
melted_df = df.melt(id_vars=['timestamp'],
value_vars=['cpu_usage', 'memory_usage', 'disk_io'],
var_name='metric',
value_name='value')
print("Данные после melt (длинный формат):")
print(melted_df)
Параметры функции:
id_vars
— столбцы, которые остаются неизменными (идентификаторы)value_vars
— столбцы для “расплавления”var_name
— имя нового столбца с названиями переменныхvalue_name
— имя нового столбца со значениями
Pivot: обратно в широкий формат
Теперь вернём данные в широкий формат с помощью pivot()
:
# Возвращаем в широкий формат
pivoted_df = melted_df.pivot(index='timestamp',
columns='metric',
values='value')
print("Данные после pivot (широкий формат):")
print(pivoted_df)
# Сброс индекса для более привычного вида
pivoted_df = pivoted_df.reset_index()
print("\nПосле reset_index():")
print(pivoted_df)
Практические кейсы: работа с логами и метриками
Рассмотрим реальный пример — обработка логов веб-сервера с несколькими серверами:
# Пример с логами нескольких серверов
server_logs = {
'date': ['2024-01-01', '2024-01-02', '2024-01-03'],
'server1_requests': [1200, 1350, 1180],
'server2_requests': [980, 1100, 1050],
'server3_requests': [1500, 1420, 1600],
'server1_errors': [12, 8, 15],
'server2_errors': [5, 12, 8],
'server3_errors': [18, 16, 22]
}
logs_df = pd.DataFrame(server_logs)
print("Логи серверов (широкий формат):")
print(logs_df)
# Melt для requests
requests_melted = logs_df.melt(id_vars=['date'],
value_vars=['server1_requests', 'server2_requests', 'server3_requests'],
var_name='server',
value_name='requests')
# Очистка названий серверов
requests_melted['server'] = requests_melted['server'].str.replace('_requests', '')
print("\nЗапросы в длинном формате:")
print(requests_melted)
Продвинутые техники и автоматизация
Для автоматизации мониторинга часто нужно обрабатывать данные с разными типами метрик. Вот более сложный пример:
# Функция для автоматической обработки серверных метрик
def process_server_metrics(df, metric_prefix='server'):
"""
Автоматически обрабатывает метрики серверов
"""
# Находим все столбцы с метриками
metric_columns = [col for col in df.columns if col.startswith(metric_prefix)]
# Melt для всех метрик
melted = df.melt(id_vars=[col for col in df.columns if col not in metric_columns],
value_vars=metric_columns,
var_name='metric_server',
value_name='value')
# Разделяем сервер и тип метрики
melted[['server', 'metric_type']] = melted['metric_server'].str.split('_', n=1, expand=True)
melted = melted.drop('metric_server', axis=1)
return melted
# Пример использования
processed_metrics = process_server_metrics(logs_df)
print("Автоматически обработанные метрики:")
print(processed_metrics.head(10))
Сравнение производительности и альтернативы
Метод | Скорость | Память | Гибкость | Лучше для |
---|---|---|---|---|
melt() | Быстро | Средне | Высокая | Простые преобразования |
pivot() | Быстро | Средне | Средняя | Уникальные индексы |
pivot_table() | Медленно | Высокое | Очень высокая | Агрегация данных |
stack()/unstack() | Средне | Низкое | Низкая | Работа с индексами |
Для больших объёмов данных (логи за месяц и более) рекомендую использовать Dask или Polars как альтернативу pandas.
Интеграция с другими пакетами
Эти функции отлично работают в связке с другими инструментами:
# Пример с Matplotlib для визуализации
import matplotlib.pyplot as plt
# Создаём данные для графика
melted_for_plot = df.melt(id_vars=['timestamp'],
value_vars=['cpu_usage', 'memory_usage'],
var_name='metric',
value_name='value')
# Построение графика
melted_for_plot['timestamp'] = pd.to_datetime(melted_for_plot['timestamp'])
for metric in melted_for_plot['metric'].unique():
data = melted_for_plot[melted_for_plot['metric'] == metric]
plt.plot(data['timestamp'], data['value'], label=metric)
plt.legend()
plt.title('Server Metrics Over Time')
plt.xticks(rotation=45)
plt.tight_layout()
# plt.show() # Раскомментируйте для показа графика
Скрипты для автоматизации
Создадим готовый скрипт для обработки логов сервера:
#!/usr/bin/env python3
"""
Скрипт для автоматической обработки логов сервера
Использование: python log_processor.py input.csv output.csv
"""
import pandas as pd
import sys
import argparse
def main():
parser = argparse.ArgumentParser(description='Process server logs')
parser.add_argument('input', help='Input CSV file')
parser.add_argument('output', help='Output CSV file')
parser.add_argument('--format', choices=['wide', 'long'], default='long',
help='Output format (default: long)')
args = parser.parse_args()
# Читаем данные
df = pd.read_csv(args.input)
if args.format == 'long':
# Преобразуем в длинный формат
result = df.melt(id_vars=['timestamp'],
var_name='metric',
value_name='value')
else:
# Предполагаем, что данные уже в длинном формате
result = df.pivot(index='timestamp',
columns='metric',
values='value').reset_index()
# Сохраняем результат
result.to_csv(args.output, index=False)
print(f"Processed {len(df)} rows, saved to {args.output}")
if __name__ == '__main__':
main()
Типичные ошибки и как их избежать
Вот самые частые проблемы и их решения:
- Дублирующие индексы в pivot() — используйте
pivot_table()
с агрегацией - Пропущенные значения — добавьте
fill_value=0
в pivot() - Неправильные типы данных — проверяйте dtypes перед преобразованием
- Проблемы с памятью — используйте
chunksize
для больших файлов
# Пример обработки больших файлов
def process_large_logs(filename, chunksize=10000):
"""Обработка больших логов по частям"""
chunks = []
for chunk in pd.read_csv(filename, chunksize=chunksize):
processed_chunk = chunk.melt(id_vars=['timestamp'],
var_name='metric',
value_name='value')
chunks.append(processed_chunk)
return pd.concat(chunks, ignore_index=True)
Новые возможности в автоматизации
Эти функции открывают множество возможностей для автоматизации:
- Динамическое создание дашбордов — длинный формат идеален для Plotly/Dash
- Автоматическая агрегация метрик — легко группировать по времени и серверам
- Интеграция с системами мониторинга — форматирование для Grafana/Prometheus
- Автоматизация отчётов — преобразование для Excel/PDF отчётов
Если вы планируете развернуть систему мониторинга на собственном сервере, рекомендую обратить внимание на VPS-решения для небольших проектов или выделенные серверы для high-load систем.
Выводы и рекомендации
Функции melt()
, pivot()
и pivot_table()
— это фундаментальные инструменты для работы с данными. Используйте их когда:
- melt() — нужно преобразовать широкие данные в длинные для анализа или визуализации
- pivot() — требуется обратное преобразование с уникальными индексами
- pivot_table() — необходима агрегация данных при преобразовании
Эти функции особенно полезны для:
- Обработки логов веб-серверов
- Анализа метрик системы
- Подготовки данных для машинного обучения
- Создания отчётов и дашбордов
Помните о производительности при работе с большими объёмами данных и не забывайте про альтернативы вроде Dask для действительно больших датасетов. Автоматизируйте рутинные задачи с помощью скриптов — это сэкономит массу времени в долгосрочной перспективе.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.