繁体   English   中英

我可以使用 python 对 Apache beam PCollection 中的项目进行排序吗?

[英]Can I sort the items in an Apache beam PCollection using python?

我可以使用 python 对 Apache beam PCollection 中的项目进行排序吗?

我需要执行依赖于要排序的项目的操作(转换)。 但到目前为止,我找不到 Apache 光束的任何“排序”机制的踪迹。

我的用例不适用于直播。 我知道当数据是实时的和/或无限的时候谈论排序是没有意义的。 这是对离线数据集的操作。

这可能吗?

显然,这是不可能的 至少,到目前为止,我找不到任何方法来做到这一点。 而且顺理成章地想,既然Beam支持stream处理和批处理一样,排序肯定是流式不行的,那么逻辑上的结论是Beam根本不支持排序。

但是,仍然可能有一些用例,您认为它们依赖于排序,但您仍然可以在不实际对项目进行排序的情况下实现它们。 我的案例就是其中之一。

为了扩展我的用例,我想找到列表中的第 n 个项目来实现分桶。 就像如果我想将我的数据集分桶成 4 个箱子并且我在数据集中共有 100 个项目,我将需要列表中的第 1、25、50、75 和 100 个项目,这样我的所有箱子都有相同的编号其中的项目。

最初,我认为我需要对列表进行排序并从中取出提到的项目。 而且由于 Beam 不支持排序,所以这是不可能的。 但是后来,我找到了另一种做同样事情的方法:

import apache_beam as beam


with beam.Pipeline() as p:
    all_items = (
        p
        | 'Create dummy data' >> beam.Create([i for i in range(100)])
    )

    item_1st = (
        all_items
        | '1st item' >> beam.combiners.Top.Smallest(1)
        | 'FlatMap_1 for 1st' >> beam.FlatMap(lambda record: record)
    )

    item_25th = (
        all_items
        | '75 largest items' >> beam.combiners.Top.Largest(75)
        | 'FlatMap_1 for 25' >> beam.FlatMap(lambda record: record)
        | '25th item' >> beam.combiners.Top.Smallest(1)
        | 'FlatMap_2 for 25' >> beam.FlatMap(lambda record: record)
    )

    item_50th = (
        all_items
        | '50 largest items' >> beam.combiners.Top.Largest(50)
        | 'FlatMap_1 for 50' >> beam.FlatMap(lambda record: record)
        | '50th item' >> beam.combiners.Top.Smallest(1)
        | 'FlatMap_2 for 50' >> beam.FlatMap(lambda record: record)
    )

    item_75th = (
        all_items
        | '25 largest items' >> beam.combiners.Top.Largest(25)
        | 'FlatMap_1 for 75' >> beam.FlatMap(lambda record: record)
        | '75th item' >> beam.combiners.Top.Smallest(1)
        | 'FlatMap_2 for 75' >> beam.FlatMap(lambda record: record)
    )

    item_100th = (
        all_items
        | '100th item' >> beam.combiners.Top.Largest(1)
        | 'FlatMap_1 for 100st' >> beam.FlatMap(lambda record: record)
    )

    _ = (
        (item_1st, item_25th, item_50th, item_75th, item_100th)
        | beam.Flatten()
        | f'All bins' >> beam.combiners.ToList()
        | beam.io.WriteToText('data/bins.txt')
    )

此代码返回如下内容:

[99, 0, 50, 75, 25]

这里有几个注意事项。 首先,如您所见,最终的 output 包含我们预期的数字,但顺序错误。 那是因为 Beam 不保证 output 中项目的顺序。其次,如果您运行代码,您可能会得到相同的答案,但顺序不同。 那是因为 Beam 中项目的顺序是随机的。

最后,我只想指出,我提供的代码并不是我原来问题的答案。 答案是Beam 不支持排序 但是,可能还有其他方法可以实现您想要做的事情。 尽管如此,如果您确定您的情况需要排序,那么不幸的是,Beam 对您来说并不实用。

暂无
暂无

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

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