当前位置: 首页 > 知识库问答 >
问题:

Spark 2.2.0 API:我应该选择使用Groupby与aggregate相结合的数据集,还是使用ReduceBykey的RDD

林星华
2023-03-14

大家好,首先,根据标题,有人可能会说这个问题已经得到了回答,但我的观点是比较特定于数据集和RDD API的RedueBykey、GroupBykey性能。我在许多帖子中看到,RedueBykey方法的性能比GroupByKey更有效,当然我同意这一点。尽管如此,我有点困惑,我无法弄清楚如果我们使用数据集或RDD,这些方法的行为如何。每种情况下应该使用哪一个?

我会尽量说得更具体一些,因此我会提供我的问题和解决方案以及工作代码,我会在您方便的时候尽早向我提出改进建议。

+---+------------------+-----+
|id |Text1             |Text2|
+---+------------------+-----+
|1  |one,two,three     |one  |
|2  |four,one,five     |six  |
|3  |seven,nine,one,two|eight|
|4  |two,three,five    |five |
|5  |six,five,one      |seven|
+---+------------------+-----+

这里的重点是检查第二个哥伦布的每一行是否包含第三个哥伦布,然后收集它们的所有ID。例如,第三列的单词“one”出现在第二列的句子中,ID为1、5、2、3。

+-----+------------+
|Text2|Set         |
+-----+------------+
|seven|[3]         |
|one  |[1, 5, 2, 3]|
|six  |[5]         |
|five |[5, 2, 4]   |
+-----+------------+

这是我的工作代码

List<Row> data = Arrays.asList(
                RowFactory.create(1, "one,two,three", "one"),
                RowFactory.create(2, "four,one,five", "six"),
                RowFactory.create(3, "seven,nine,one,two", "eight"),
                RowFactory.create(4, "two,three,five", "five"),
                RowFactory.create(5, "six,five,one", "seven")
        );

        StructType schema = new StructType(new StructField[]{
                new StructField("id", DataTypes.IntegerType, false, Metadata.empty()),
                new StructField("Text1", DataTypes.StringType, false, Metadata.empty()),
                new StructField("Text2", DataTypes.StringType, false, Metadata.empty())
        });

        Dataset<Row> df = spark.createDataFrame(data, schema);
        df.show(false);
        Dataset<Row> df1 = df.select("id", "Text1")
                .crossJoin(df.select("Text2"))
                .filter(col("Text1").contains(col("Text2")))
                .orderBy(col("Text2"));

        df1.show(false);

        Dataset<Row> df2 = df1
                .groupBy("Text2")
                .agg(collect_set(col("id")).as("Set"));

        df2.show(false);

我的问题在3个子序列中详细说明:

  • 为了提高性能,我是否需要在RDD中转换数据集并生成ReduceBykey而不是数据集groupby

共有1个答案

斜浩穰
2023-03-14

TL;DR两者都不好,但如果您使用的是数据集,请继续使用数据集。

Dataset.groupBy如果与合适的函数一起使用,则行为类似于还原ByKey。不幸的是,collect_set的行为非常类似于groupByKey,如果重复次数很少。用还原ByKey重写它不会改变任何事情。

如果你能给出一个更有效的替代解决方案,我将不胜感激

您所能做的就是删除CrossJoin

val df = Seq((1, "one,two,three", "one"),
  (2, "four,one,five", "six"),
  (3, "seven,nine,one,two", "eight"),
  (4, "two,three,five", "five"),
  (5, "six,five,one", "seven")).toDF("id", "text1", "text2")

df.select(col("id"), explode(split(col("Text1"), ",")).alias("w"))
  .join(df.select(col("Text2").alias("w")), Seq("w"))
  .groupBy("w")
  .agg(collect_set(col("id")).as("Set")).show

+-----+------------+
|    w|         Set|
+-----+------------+
|seven|         [3]|
|  one|[1, 5, 2, 3]|
|  six|         [5]|
| five|   [5, 2, 4]|
+-----+------------+
 类似资料:
  • 问题内容: 我正在使用c / c 为osx和linux开发命令行界面可执行文件。该项目将链接到opencv。我应该使用libc 还是libstdc ++? 问题答案: 我会为每个操作系统使用本机库,即GNU / Linux上的libstdc 和Mac OS X上的libc 。 libc 在GNU / Linux上不是100%完整的,而libstdc 更完整时使用libc并没有真正的优势。另外,如果

  • 问题内容: 和CSS 和有什么不一样?我应该使用哪一个?为什么? 问题答案: 所有这些答案似乎都是不正确的。与直觉相反,在CSS 中不是pixel 。至少不是在简单的物理意义上。 从W3C,EM,PX,PT,CM,IN…阅读本文,了解如何为CSS发明一个“神奇的”单元。的含义因硬件和分辨率而异。(该文章是最新的,最新更新为2014-10。) 我自己的思考方式: px单位是CSS的魔术单位。它与当前

  • 问题内容: 我正在一个将Angular和Underscore都作为依赖项的项目。 当我需要创建对象的副本时,根据当时的心情,我可以使用或 在我看来,这些方法中的一种可能比另一种更快速/可靠/健壮。 假设已经包含两个库,那么这两个函数中的任何一个是否存在使另一个函数更好或更坏使用的已知问题? 问题答案: 关于您的问题: angular.copy和_.clone是不同的。这不是哪个更好的问题,而是关于

  • 问题内容: 我想从文本文件中读取每一行并将它们存储在ArrayList中(每一行是ArrayList中的一项)。 到目前为止,我知道BufferedInputStream写入缓冲区,并且仅在缓冲区为空时才进行另一次读取,这可以最大程度地减少或至少减少操作系统的操作量。 我正确吗-我说得通吗? 如果以上情况是在任何情况下,任何人都想使用DataInputStream。最后,我应该使用这两个中的哪一个

  • 假设我有一个方法将只读视图返回到成员列表中: 进一步假设客户机所做的只是立即对列表进行一次迭代。也许是为了把玩家放进一个JList或者别的什么。客户端没有存储对列表的引用以供以后检查! 对于这种常见的场景,我是否应该返回一个流呢? 还是返回流在Java中不是惯用的?流被设计成总是在创建它们的同一个表达式中“终止”吗?

  • 问题内容: 在numpy中,可以使用切片语法中的’newaxis’对象创建长度为1的轴,例如: 该文档的状态是一个也可以用代替,效果是完全一样的。 有什么理由选择一个?是否有一般偏好或样式指南?我的印象是更受欢迎,可能是因为它更明确。那么,有什么理由允许这样做? 问题答案: 之所以被允许,是因为它仅仅是的别名。 作者之所以选择它,是因为他们需要一个方便的常量并且可用。 至于为什么你应该更喜欢过:主