Оконные вычисления — Window

Преобразование window выполняет вычисления над отсортированными группами объектов данных. Это может быть ранжирование, анализ предыдущих и следующих значений, а также агрегирование: например, накопленные суммы и средние. Вычисленные значения записываются обратно во входной поток данных и становятся доступны для кодирования.

Рассмотрим накопленное распределение частот:

import altair as alt
from altair.datasets import data

alt.Chart(data.movies.url).transform_aggregate(
    count='count(*)',
    groupby=['IMDB Rating']
).transform_window(
    sort=[{'field': 'IMDB Rating'}],
    frame=[None, 0],
    cumulative_count='sum(count)',
).mark_area().encode(
    x='IMDB Rating:Q',
    y='cumulative_count:Q',
)

Сначала данные агрегируются: фильмы группируются по оценке IMDB и подсчитываются. В полученном наборе каждая строка содержит уникальную оценку IMDB и число фильмов с такой оценкой.

Затем применяется оконное преобразование с определением поля сортировки. Оно задаёт порядок объектов внутри окна: здесь фильмы сортируются по оценке IMDB.

Параметр frame указывает, сколько объектов до и после текущего объекта включать в окно. Здесь включаются все фильмы до текущего включительно.

Наконец, определение оконного поля задаёт способ агрегирования объектов в окне. Здесь количества складываются, чтобы получить накопленное число фильмов.

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

Функция Параметр Описание
row_number Нет Присваивает каждому объекту последовательный номер строки, начиная с 1.
rank Нет Присваивает ранг внутри окна, начиная с 1. Равные значения получают один ранг. Последующие ранги учитывают число предшествующих значений: если первые два значения имеют ранг 1, третье получает ранг 3.
dense_rank Нет Присваивает плотный ранг, начиная с 1. Равные значения получают один ранг, но число предшествующих значений не учитывается: после двух значений с рангом 1 третье получает ранг 2.
percent_rank Нет Присваивает процентный ранг по формуле (rank - 1) / (group_size - 1).
cume_dist Нет Присваивает значение накопленного распределения от 0 до 1.
ntile Число Присваивает значение квантильной группы, например процентиля. Целочисленный параметр задаёт число групп: 100 для процентилей, 5 для квинтилей.
lag Число Возвращает значение объекта, находящегося на заданное число позиций перед текущим; если его нет — null. Параметр смещения по умолчанию равен 1. Для операции нужна соответствующая запись в массиве fields.
lead Число Возвращает значение объекта, находящегося на заданное число позиций после текущего; если его нет — null. Параметр смещения по умолчанию равен 1. Для операции нужна соответствующая запись в массиве fields.
first_value Нет Возвращает значение первого объекта текущего скользящего окна. Нужна соответствующая запись в массиве fields.
last_value Нет Возвращает значение последнего объекта текущего скользящего окна. Нужна соответствующая запись в массиве fields.
nth_value Число Возвращает значение n-го объекта текущего скользящего окна; если его нет — null. Требуется неотрицательный целочисленный параметр, задающий смещение от начала окна. Нужна соответствующая запись в массиве fields.

В отличие от aggregate, вычисляющего одно итоговое значение для всех объектов, window добавляет новое свойство каждому объекту. Оно вычисляется по соседним объектам, ограниченным определением окна.

Рассмотрим временные ряды цен акций:

import altair as alt
from altair.datasets import data

alt.Chart(data.stocks.url).mark_line().encode(
    x='date:T',
    y='price:Q',
    color='symbol:N',
)

Общую картину трудно увидеть: цена акций Google значительно выше остальных. Если показать z-оценки вместо самих цен, картина становится яснее:

import altair as alt
from altair.datasets import data

alt.Chart(data.stocks.url).transform_window(
    mean_price='mean(price)',
    stdev_price='stdev(price)',
    frame=[None, None],
    groupby=['symbol'],
).transform_calculate(
    z_score=(alt.datum.price - alt.datum.mean_price) / alt.datum.stdev_price,
).mark_line().encode(
    x='date:T',
    y='z_score:Q',
    color='symbol:N',
)

Две функции агрегирования, mean и stdev, внутри оконного преобразования позволяют вычислить z-оценки с помощью calculate.

Подробнее об аргументах см. класс WindowTransform и документацию Vega-Lite.

Параметры преобразования

Метод Chart.transform_window основан на классе WindowTransform, который поддерживает следующие параметры:

Нажмите, чтобы показать таблицу
СвойствоТипОписание
framearray([null, number])

Массив из двух элементов, задающий границы скользящего окна. Число означает смещение от текущего объекта; null — отсутствие ограничения на предшествующие или последующие строки. [null, 0] включает текущий и все предыдущие объекты; [-5, 5] — пять объектов до и пять после текущего; [null, null] — все объекты данных. Если при полном окне нужно присвоить всем объектам одно значение, можно использовать более простое агрегирование с присоединением. Границы окна влияют только на агрегирование и функции first_value, last_value, nth_value; остальные оконные функции от них не зависят. По умолчанию: [null, 0].

groupbyarray(FieldName)

Поля для разделения объектов данных на отдельные окна. Если не заданы, все точки входят в одно окно.

ignorePeersboolean

Игнорировать ли при задании границ окна равные значения, считающиеся одинаковыми по критериям сортировки. По умолчанию false: окно расширяется, чтобы включить все такие значения. При true границы задаются только смещениями. Настройка влияет лишь на операции, зависящие от границ окна: агрегирование, first_value, last_value и nth_value. По умолчанию: false.

sortarray(SortField)

Определение поля сортировки объектов внутри окна. Объекты, равные по компаратору, считаются равными по рангу. Если сортировка не задана, порядок не определён: объекты обрабатываются в порядке поступления, ни один не считается равным другому; ignorePeers игнорируется и трактуется как true.

windowarray(WindowFieldDef)

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