Обработка данных и визуализация с помощью Pandas, Matplotlib и Seaborn

Что ж, пришло время для еще одной части анализа временных рядов. На этот раз я сосредоточусь на двух вещах: а) преобразовании обычного фрейма данных в правильный формат для анализа; и б) осмысление этих данных посредством визуализации.

Первая цель очень важна. Обработка и очистка данных - важное дело в науке о данных, особенно в анализе временных рядов. Даже для базового анализа легче работать с данными, которые находятся в хорошей форме. Для расширенного моделирования, такого как прогнозирование, часто бывает обязательным иметь правильный формат, чтобы библиотека программирования могла распознать его как объект временного ряда.

Остальная часть статьи разделена на две части: в первой я рассмотрю обычный ритуал формирования и исследовательского анализа данных, а во второй части я сосредоточусь на различных способах визуализации данных временных рядов.

Давайте нырнем!

Часть A. Обработка данных

Сразу хочу сказать, что я не рассматриваю в этом разделе - переименование столбцов, разбиение данных на подмножества, изменение типов данных (например, string на int) и лечение отсутствующих значений. Чтобы эта статья была сосредоточена на формировании временных рядов, я не буду их здесь рассматривать, но если вам интересно, вы можете проверить мою предыдущую статью - Контрольный список для обработки данных.

i) Импортировать библиотеки

Как обычно, я использую pandas для обработки данных и использую matplotlib и seaborn для визуализации.

# pandas for data wrangling
import pandas as pd
# seaborn and matplotlib for visualization
import seaborn as sns
import matplotlib.pyplot as plt

ii) Импорт данных

Для этого упражнения я загрузил интересный набор данных о ежемесячных розничных продажах книг (в миллионах долларов США), о которых сообщают книжные магазины по всей территории США. Диапазон дат - между 1992 и 2018 годами.

Вы можете загрузить данные из баз данных Бюро переписи населения (census.gov), чтобы следить за ними, но я бы посоветовал выбрать другую, с которой вы лучше знакомы.

Итак, после некоторой начальной очистки я загружаю данные и исследую несколько вещей, вызывая функции head() и info().

# load in data
df = pd.read_csv("BookSales.csv")
# data structure
df.head()
df.info()

Одна из ключевых вещей, на которую я обращаю внимание, заключается в том, что измерение времени записывается в формате «мм / гггг» и сохраняется как строка / объект (см. Вывод функции info()).

iii) Создание объекта datetime

В этой части мы хотим достичь 3 целей:

  • преобразовать столбец «Период» в объект datetime
  • установить новый столбец datetime как индекс фрейма данных
  • создать дополнительные столбцы «месяц» и «год» для упрощения визуализации
# converting dates/time columns into a datetime object
df["Period"] = pd.to_datetime(df["Period"])
# set the new datetime column as the index
df = df.set_index("Period")
# create new columns from datetime index
df["year"] = df.index.year
df["month"] = df.index.month
# new dataframe
df.head()

iv) Преобразование полной формы в широкую

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

У данных длинного формата будет намного больше строк, чем у данных широкого формата, но это то, что предпочитают специалисты по данным, потому что с ними легко работать с «аккуратными» данными в библиотеках программирования.

x = df.groupby(["year", "month"])["Value"].mean()
df_wide = x.unstack()
df_wide.head()

v) Фильтрация по индексу datetime

Теперь, когда мы преобразовали «нормальный» фрейм данных в объект datetime, пора применить эту новообретенную силу в действии! Теперь вы можете запрашивать данные по любой конкретной дате.

# filter by date
df.loc["2016-01-01"]
>> Value    1428.0
year     2016.0
month       1.0
Name: 2016-01-01 00:00:00, dtype: float64

Вы также можете фильтровать данные по дате, месяцу и году. Фильтрация настолько проста и интуитивно понятна, насколько это возможно.

# filter by a date range
df.loc["2016-01-01": "2016-12-01"]
# filter by month
df.loc["2008-01"]
# filter by month range
df.loc["2010-01": "2010-05"]
# filter by year
df.loc["2006"]
# filter by year range
df.loc["2011": "2012"]

vi) Передискретизация

Передискретизация - это способ группировки данных по единицам времени - день, месяц, год и т. Д. Ниже приведен пример повторной выборки по месяцам («M»). Вы также можете использовать «A» для года и «D» дни в зависимости от ситуации.

# resampling by month
df["Value"].resample("M").mean()

Vii) Скользящее среднее

Скользящее среднее - это мощный метод сглаживания изменений во временном тренде, который осуществляется путем взятия среднего значения из прошлых наблюдений. В следующем разделе мы увидим, как визуализировать скользящие средние, а вот как работает код.

# rolling window/moving average of N past observations
df["Value"].rolling(window=6).mean()

Часть B: Визуализация

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

Ниже приведены 8 различных техник визуализации. Это все, что вам нужно знать? Короткий ответ - если вы знаете, как создавать и интерпретировать эти 8 визуализаций, вы в довольно хорошей форме!

Я не собираюсь писать сложные коды для создания красивых фигур, вместо этого я использую параметры по умолчанию seaborn в однострочном коде. Как индивидуум, вы можете настроить эти фигурки по своему желанию, исходя из своего вкуса и чувства прекрасного!

Кроме того, как вы заметили, я использую только seaborn в качестве библиотеки для печати. Существуют всевозможные модные библиотеки, но, опять же, я бы все оставил простым и приятным.

i) Простой сюжет

Простой график действительно прост, он просто отображает столбец значений в зависимости от измерения времени.

# simple time series plot
sns.lineplot(data = df["Value"])

ii) Нарезка

Иногда вам может потребоваться увеличить масштаб до определенного диапазона дат и периода времени.

# zooming in on specific date range
drange = df.loc["2011": "2015"]
sns.lineplot(data = drange["Value"])

iii) повторная выборка

Мы говорили о передискретизации в предыдущем разделе, но теперь давайте посмотрим, как выглядят передискретизированные данные.

# plotting resampled data 
resampled = df["Value"].resample("A").mean() 
sns.lineplot(data = resampled)

iv) Скользящее среднее

Скользящее среднее похоже на повторную выборку, но имеет большую гибкость, вы можете указать любое количество прошлых наблюдений в виде скользящего окна. Ниже приведен пример с использованием движущегося окна из 6 прошлых наблюдений.

# plotting moving average (window = N past observations)
ma = df["Value"].rolling(window=6).mean() 
sns.lineplot(data = ma)

v) Коробчатая диаграмма

В любом исследовательском анализе данных коробчатые диаграммы являются наиболее полезными статистическими графиками для понимания как центральной тенденции, так и распределения данных. В некоторой степени это также полезно для данных временных рядов. Ниже приведен пример месячных диаграмм значений.

# boxplots by month
sns.boxplot(x = 'month', y='Value', data = df)

[Я не пробовал, но думаю, что с помощью той же строчки кода можно рисовать скрипичные сюжеты. Давай, попробуй, просто замените boxplot на violinplot!]

vi) Barplot

Гистограммы - это старая техника визуализации, и я не знаю, используют ли люди их слишком часто в своих проектах. Но я включаю это сюда, чтобы вы знали, что они существуют!

# barplot
sns.barplot(x = 'month', y='Value', data = df)

vii) Временные ряды с доверительными интервалами

Также возможно визуализировать временные ряды, показывающие как тренд, так и доверительные интервалы (то есть изменение данных в каждый момент времени).

# plotting with confidence intervals 
sns.lineplot(x="year", y="Value", data=df)

viii) Построение широкоформатных данных

И последнее, но не менее важное: помните, что вначале мы создавали данные широкого формата, и теперь пришло время применить их на практике. Используя приведенную ниже технику визуализации, мы теперь видим тенденции в данных за каждый месяц отдельно.

# plotting wideform data
sns.lineplot(x="year", y="Value", data=df, hue="month", palette="Dark2")

Последняя мысль

Цель этой статьи заключалась в том, чтобы собрать в одном месте большинство техник обработки и визуализации данных, которые могут понадобиться вам как начинающему или промежуточному аналитику временных рядов. Во-первых, мы увидели, как преобразовать обычный фрейм данных в мощный объект datetime и использовать его для фильтрации и визуализации. Во второй части мы создали 8 разных графиков, используя разные техники для визуализации временных рядов. Следующим шагом было бы выбрать другой набор данных, воспроизвести результаты и поиграть с другими параметрами построения.

Надеюсь, это был полезный пост. Если у вас есть комментарии, не стесняйтесь записывать их ниже. Вы можете подписаться на меня в Medium, Twitter или LinkedIn.