Временные ряды с Julia с библиотекой TimeSeries.jl

826344ee7366240e83cb8efcdf301deb.png

Julia позволяет достигать скорости, сравнимой с C, что делает её хорошим выбором для временных рядов.

Пакет TimeSeries предоставляет удобные методы для работы с данными временных рядов в Julia.

Установка

Активируем менеджер пакетов, нажав клавишу ]. Приглашение командной строки изменится на (v1.x) pkg>, где x текущая версия Julia:

В режиме менеджера пакетов юзаем команду:

add TimeSeries

Команда автоматически найдет, загрузит и установит пакет TimeSeries.jl, а также все его зависимости.

После установки можно чекнуть, установлен ли пакет с помощью:

using TimeSeries

Тип TimeArray

TimeArray — это структура данных, разработанная для хранения и обработки временных рядов. Она содержит следующее:

  • Timestamps: метки времени, указывающие на конкретные моменты времени для каждого наблюдения.

  • Values: значения данных, соответствующие каждой метке времени.

  • Columns: имена столбцов, представляющие различные переменные или измерения временного ряда.

  • Metadata: доп. данные, которые могут быть ассоциированы с временным рядом.

Для создания объекта TimeArray необходимо предоставить данные о времени, значения и, опционально, имена столбцов и метаданные:

using TimeSeries
using Dates

dates = Date(2023, 1, 1):Day(1):Date(2024, 1, 5)
values = [101, 102, 103, 104, 105]
ta = TimeArray(dates, values, ["Price"])

Здесь создали временной ряд с ежедневными данными о цене за первые пять дней января 2023 года.

Доступ к данным в TimeArray можно получить разными способами. Например, для получения значений:

ta.values

Для доступа к меткам времени:

ta.timestamp

И для получения имен столбцов:

ta.colnames

Индексация

В TimeSeries.jl индексация TimeArray осуществляется не только по числовым индексам, но и по временным меткам.

Допустим, есть временной ряд, представленный объектом TimeArray. Можно обращаться к его элементам, используя метки времени:

using TimeSeries, Dates

# пример временного ряда
dates = Date(2024, 1, 1):Day(1):Date(2024, 1, 5)
data = rand(5, 2) # случайные данные для примера
ta = TimeArray(dates, data, ["Column1", "Column2"])

# индексация по одной дате
ta[Date(2024, 1, 3)]

Код вернет значения TimeArray за 3 января 2024 года.

Можно выбрать данные за определенный период времени, используя диапазон дат:

ta[Date(2024, 1, 2):Date(2024, 1, 4)]

Запрос вернет данные за период с 2 по 4 января 2024 года.

Индексация по условию позволяет выбирать данные на основе логического условия:

ta[ta.timestamp .> Date(2024, 1, 2)]

Этот пример вернет все данные, начиная с 3 января 2024 года.

В дополнение к временной индексации, TimeArray поддерживает индексацию по столбцам:

# индексация по имени столбца
ta["Column1"]

# индексация по нескольким столбцам
ta[[:Column1, :Column2]]

Запросы вернут данные только для указанных столбцов.

TimeSeries.jl также поддерживает комбинированную индексацию:

# комбинированная индексация по дате и столбцу
ta[Date(2024, 1, 3), "Column1"]

Запрос вернет значение из столбца Column1 за 3 января 2024 года.

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

ta[findall(x -> month(x) == 1, ta.timestamp)]

Вернутся все данные за январь 2024 года.

Разделение временных рядов по условиям

Разделение временных рядов по условиям позволяет разделить временной ряд на несколько частей на основе определенных критериев.

Функция split в TimeSeries.jl позволяет разделить TimeArray на несколько частей по заданному условию. Условие может быть основано на значениях данных, метках времени или метаданных. Результаом работы split является массив TimeArray объектов, каждый из которых соответствует сегменту данных, удовлетворяющему определенному условию.

Предположим, есть временной ряд, который хочется разделить на две части: одна содержит значения выше определенного порога, а другая — ниже:

using TimeSeries, Dates

# пример временного ряда
dates = Date(2024, 1, 1):Day(1):Date(2024, 1, 10)
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ta = TimeArray(dates, data, ["Value"])

# Разделение по условию значения > 5
split_arrays = split(ta, ta[:Value] .> 5)

split вернет массив из двух TimeArray объектов: первый для значений Value > 5 и второй для остальных.

Можно также разделить временной ряд на основе даты:

split_date = Date(2024, 1, 5)
split_arrays = split(ta, ta.timestamp .<= split_date)

Здесь временной ряд разделяется на две части: до и после 5 января 2024 года.

Разделение временного ряда по дням недели:

# разделение по дню недели (например, выходные и будние)
is_weekend = x -> dayofweek(x) in (6, 7)
split_arrays = split(ta, is_weekend.(ta.timestamp))

split создает два TimeArray объекта: один для выходных дней и другой для будних.

Изменение существующих TimeArray

Для изменения значений в TimeArray, можно использовать индексацию для доступа к конкретным элементам и присвоить им новые значения:

using TimeSeries, Dates

# пример временного ряда
dates = Date(2024, 1, 1):Day(1):Date(2024, 1, 5)
data = [1, 2, 3, 4, 5]
ta = TimeArray(dates, data, ["Value"])

# изменяем значение на второй дате
ta[2] = 10

Код изменит значение во второй строке TimeArray на 10.

Можно добавить новые столбцы к существующему TimeArray с помощью функции merge, которая объединяет два TimeArray объекта. Для удаления столбцов есть функция delete:

# новый столбец данных
new_data = [6, 7, 8, 9, 10]
new_column = TimeArray(dates, new_data, ["NewValue"])

# новый столбец к существующему TimeArray
merged_ta = merge(ta, new_column)
# удаляем столбец "NewValue"
reduced_ta = delete(merged_ta, :NewValue)

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

# функция удвоения к каждому значению
doubled_ta = map(x -> x * 2, ta)

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

# увеличиваем каждое значение на 1
incremented_ta = ta .+ 1

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

© Habrahabr.ru