繁体   English   中英

Palantir Typescript 在 Workshop 中的 Top N 排序

[英]Palantir Typescript Top N sort in Workshop

我对 Palantir 中的 typescript 和 Workshop 的概念不熟悉。

1)我希望能够展示具有特定特征的顶级 GROUP(例如总 AMOUNT)。 GROUP 超过 12,000 个(因此超过了 Palantir 的限制)。

我尝试指定:有超过 12000 个类别,我会计算每个类别的总和(对于列 AMOUNT)!

有什么方法可以避免近似结果并按金额显示前 100 个组(降序)? 我希望我可以通过Pivot TableHistogram来做到这一点。 此外,我希望能够显示前 100 个组的正确总和(或者更好的是,选择的直方图条)。

2)此外.. 在直方图上可以同时选择多个柱(不是 1 也不是全部)?!

3)我可以过滤掉谁的帖子聚合值小于某个特定的聚合值吗? (不是来自初始数据集,而是来自聚合)我可以将枢轴输出保存在对象集中吗?!

我想这两个问题都可以通过一个函数来解决,你能输入 TypeScript 代码来得到我想要的吗?

谢谢!!

如果您尝试聚合到超过 1000 个存储桶中,这可能会出现问题。 如果您的对象集大于此(或预计会在不久的将来),请使用不同的方法。

你可以在 TypeScript 中创建一个 Foundry 函数来计算聚合,然后使用这个函数来填充一个 Workshop 表。 例如,要找到沿它们行驶的总距离最大的路线(即这里的 group by 属性是routeId并且 summed 属性是distance ):

import { Function, TwoDimensionalAggregation, BucketKey, BucketValue } from "@foundry/functions-api";
import { Objects, ExampleDataFlight } from "@foundry/ontology-api";

export class MyFunctions {
    @Function()
    public async aircraftAggregationExample(): Promise<TwoDimensionalAggregation<string>> {
        const aggregation = await Objects.search().exampleDataFlight()
                 .filter(o => o.distance.range().gt(0))
                 .groupBy(o => o.routeId.topValues())
                 .sum(o => o.distance);

        return sortBucketsByValue2D(aggregation, 'desc');
    }
}

/**
 * Sort buckets of a 2D aggregation by their value in the specified order
 * 
 * Example input 1:
 * { buckets: [
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: 456 },
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: 123 },
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: 789 },
 * ]}
 * 
 * Example output 1:
 * { buckets: [
 *   { key: { min: "2021-01-01", max: "2021-12-31" }, value: 123 },
 *   { key: { min: "2022-01-01", max: "2022-12-31" }, value: 456 },
 *   { key: { min: "2023-01-01", max: "2023-12-31" }, value: 789 },
 * ]}
 * 
 * Example input 2:
 * { buckets: [
 *   { key: 17, value: 456 },
 *   { key: 21, value: 123 },
 *   { key: 23, value: 789 },
 * ]}
 * 
 * Example output 2:
 * { buckets: [
 *   { key: 21, value: 123 },
 *   { key: 17, value: 456 },
 *   { key: 23, value: 789 },
 * ]}
 */
function sortBucketsByValue2D<K extends BucketKey, V extends BucketValue>(
    buckets: TwoDimensionalAggregation<K, V>,
    order: 'asc' | 'desc' = 'asc'
): TwoDimensionalAggregation<K, V> {
    return {
        // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
        buckets: buckets.buckets.sort(({ value: v1 }, { value: v2 }) => {
            // These are be either numbers, timestamps or localdates which can be compared like this
            return (order === 'desc' ? -1 : 1) * (v1.valueOf() - v2.valueOf());
        }),
    };
}

您可以在转换中执行 1 和 3,而不是尝试在 Quiver 或 Workshop 中直接在对象顶部执行此聚合。 这将生成一个预先聚合的数据集,然后您可以从中创建一个对象。 然后,您将能够在需要聚合的 Workshop 中使用它。

这可能最适合您的数据规模,因为您提到您有 12000 个存储桶。

如果您想使用截止,转换可能如下所示:

from pyspark.sql import functions as F
from transforms.api import transform_df, Input, Output


@transform_df(
    Output("/path/to/route_aggregation"),
    source_df=Input("/path/to/flights"),
)
def compute(source_df):
    return (
        source_df
        .groupBy(F.col("route_id"))
        .agg(F.sum("distance").alias("total_distance_travelled"))
        .filter(F.col("total_distance_travelled") > 500000)
    )

或者如果你只想要前 100 名:

from pyspark.sql import functions as F, Window as W
from transforms.api import transform_df, Input, Output


@transform_df(
    Output("/path/to/route_aggregation"),
    source_df=Input("/path/to/flights"),
)
def compute(source_df):
    return (
        source_df
        .groupBy(F.col("route_id"))
        .agg(F.sum("distance").alias("total_distance_travelled"))
        .withColumn("row_number", F.row_number().over(W.orderBy(F.col("total_distance_travelled").desc())))
        .filter(F.col("row_number") <= 100)
    )

如果您在对象上使用回写,则应使用对象的回写数据集以确保聚合与您通过操作所做的任何编辑保持同步。

这种方法的缺点是您必须维护另一种对象类型,并且它不如其他对象类型灵活(因为要进行更改,您必须更改转换逻辑并可能更新您的本体定义。这也意味着有时可能聚合和单个对象值不同步,因为更新数据集需要时间。此外,这些聚合对象可能会使您的本体混乱,并且不是真正意义上的“对象”。

避免这些缺点的一种方法是,如果您可以将此聚合附加到有意义的现有对象上。 如果您有表示类别的本体对象,则此方法有效。 例如,如果您按路线对航班进行分组,然后对行驶距离求和,而不是添加新的聚合对象,您可以只向路线添加一个属性,例如“路线上行驶的总距离”。

如果您尝试聚合到超过 1000 个存储桶中,这可能会出现问题。 如果您的对象集大于此(或预计会在不久的将来),请使用不同的方法。

在 Workshop 中对聚合进行分组和排序的最简单方法是添加数据透视表。 它可以配置如下:

  • 行分组:要分组的类别
  • 聚合:总和(金额)

然后按预览中聚合列上的下拉菜单并按“降序排序”。

如果您有大量数据,您可能会收到错误消息:“ 的值太多,未显示全部。过滤您的数据以获得更准确的结果。” 在这种情况下,如果可能,您应该预先过滤您的数据(例如,删除不相关或零值)或使用其他方法之一。

如果您想将具有多种类别的大量数据聚合到直方图中进行过滤,您可能需要考虑使用 Contour 而不是 Workshop。 内置的“直方图”板似乎很适合这个,例如:

轮廓直方图板的配置,显示 y 轴列设置为“route_id”,x 轴设置为显示“距离”的“总和”

这将允许您选择多个组,然后将这些过滤器应用于直方图板下方的所有板。

您可以使用 Contour 创建仪表板,该仪表板可以具有与某些不需要操作的 Workshop 应用程序类似的功能。 您还可以使用 Contour 构建一个预聚合数据集(使用“切换到透视数据”按钮,然后使用底部的“另存为数据集”),它可以支持要在 Workshop 中使用的对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM