В системах декларативной визуализации данных Vega и Vega-Lite
трансформации формируют промежуточные этапы обработки данных внутри
графа вычислений. Одной из базовых операций является
project, предназначенная для ограничения набора полей,
проходящих через конвейер данных.
projectТрансформация project выполняет операцию проекции набора
данных, оставляя только указанные поля и удаляя остальные. Это не
вычисление новых значений и не агрегация, а структурное сокращение
записи.
Ключевая роль:
В отличие от calculate или aggregate,
project не изменяет значения — только структуру объекта
данных.
Каждый объект данных в Vega представляет собой набор ключ-значение. Например:
{
"country": "Kazakhstan",
"year": 2020,
"value": 42,
"unused_field": "noise"
}
После применения проекции:
{
"country": "Kazakhstan",
"value": 42
}
Поле year и unused_field удаляются на этапе
трансформации.
В Vega трансформация project задаётся внутри массива
transform:
{
"type": "project",
"fields": ["country", "value"]
}
Полный фрагмент data:
{
"data": [
{
"name": "table",
"values": [
{"country": "KZ", "year": 2020, "value": 10},
{"country": "KZ", "year": 2021, "value": 15}
],
"transform": [
{
"type": "project",
"fields": ["country", "value"]
}
]
}
]
}
Все поля, не перечисленные в fields, исключаются без
возможности восстановления на следующих стадиях.
Хотя логически порядок в fields может совпадать с
итоговой структурой, движок не обязан сохранять порядок ключей в
объектах JavaScript.
project не может:
project vs
calculateproject — удаляет поляcalculate — добавляет или изменяет поляПример calculate:
{
"type": "calculate",
"expr": "datum.value * 2",
"as": "double_value"
}
project vs
filterproject не изменяет количество строкfilter изменяет количество строкproject часто применяется как подготовительный этап
перед более тяжёлыми операциями:
"transform": [
{
"type": "project",
"fields": ["country", "value"]
},
{
"type": "filter",
"expr": "datum.value > 10"
},
{
"type": "calculate",
"expr": "datum.value * 100",
"as": "scaled"
}
]
Такой подход снижает нагрузку, если исходные данные содержат большое количество ненужных атрибутов.
Удаление лишних полей на раннем этапе:
expr)aggregate,
windowОсобенно заметно при больших наборах данных (десятки и сотни тысяч строк).
Если в fields указано поле, которого нет в данных:
{
"type": "project",
"fields": ["country", "missing_field"]
}
то:
Это делает трансформацию устойчивой к неоднородным данным.
project не выполняет глубокую проекцию вложенных
объектов. Для данных вида:
{
"a": 1,
"b": {
"x": 10,
"y": 20
}
}
указание:
"fields": ["b"]
сохраняет объект b целиком. Выбор b.x
невозможен без предварительной трансформации через выражения.
В Vega-Lite явного project как отдельной трансформации
нет в пользовательском API, но аналогичная логика реализуется через:
transformcalculateПри компиляции Vega-Lite в Vega может автоматически вставляться
project, если:
Если визуализация использует только две переменные:
лишние поля исключаются:
{
"type": "project",
"fields": ["category", "value"]
}
Перед aggregate:
{
"type": "project",
"fields": ["group", "amount"]
},
{
"type": "aggregate",
"groupby": ["group"],
"ops": ["sum"],
"fields": ["amount"],
"as": ["total"]
}
Удаление ненужных колонок снижает сложность агрегации.
Эти ограничения делают project строго структурной
операцией без логики.
Использование project делает конвейер данных более
явным:
Наиболее типичные связки:
project + filter — предварительная
очисткаproject + calculate — вычисление на
ограниченном наборе полейproject + aggregate — минимизация данных
перед группировкойproject + window — оптимизация оконных
вычисленийВнутренне Vega трактует project как узел графа данных,
который:
Это делает трансформацию детерминированной и без побочных эффектов.
project для фильтрации строкfieldscalculateКаждая из этих попыток приводит к неверной модели обработки данных и требует других трансформаций.