【问题标题】:Aggregate multiple columns in Spark dataframe在 Spark 数据框中聚合多个列
【发布时间】:2017-09-04 07:04:28
【问题描述】:

我在解决以下问题时遇到了问题。 基本上我想找出特定商品(item_code)在哪一天的最大和最小销量。

输入数据帧

item_code, sold_date, price, volume
101,      10-12-2017, 20,    500
101,      11-12-2017, 20,    400
201,      10-12-2017, 50,    200
201,      13-12-2017, 51,    300

预期输出

查找具有销售日期的 maxmin 卷。我想要这个解决方案,而不使用任何 lambda 操作。

df.groupBy("item_code")agg(min("volume"),max("volume"))

以上将帮助我获得maxmin 的音量,但我希望它们连同各自的日期。

我用 udf 尽力了我的水平,但我无法破解它。任何帮助高度赞赏。

【问题讨论】:

  • 请尝试发布文本示例而不是图像。谢谢。
  • 谢谢。更新了我的帖子@philantrovert
  • 它帮助我。我想要给定 item_code 的最大/最小成交量。 first() 为我的所有结果返回相同的日期。
  • 在 groupBy 子句中,分组后它将是日期列表,因此您必须在它们之间使用聚合函数进行选择。您想使用什么聚合函数?以id的另一行为例:101,应该选择什么日期?
  • 什么是“连同各自的日期”? .如果添加以下行,输出应该是什么:101、9-12-2017、20、500 和 101、6-12-2017、20、500

标签: scala apache-spark apache-spark-sql


【解决方案1】:

您想要的最终输出需要复杂的过程。您可以使用以下流程。

给定输入dataframe

+---------+----------+-----+------+
|item_code|sold_date |price|volume|
+---------+----------+-----+------+
|101      |10-12-2017|20   |500   |
|101      |11-12-2017|20   |400   |
|201      |10-12-2017|50   |200   |
|201      |13-12-2017|51   |300   |
+---------+----------+-----+------+

你可以使用下面的代码

import org.apache.spark.sql.functions._
val tempDF = df.groupBy("item_code").agg(min("volume").as("min"),max("volume").as("max"))
tempDF.as("t2").join(df.as("t1"), col("t1.item_code") === col("t2.item_code") && col("t1.volume") === col("t2.min"), "left")
  .select($"t2.item_code", $"t2.max", concat_ws(",", $"t2.item_code", $"t2.min", $"t1.sold_date").as("min"))
  .join(df.as("t3"), col("t3.item_code") === col("t2.item_code") && col("t3.volume") === col("t2.max"), "left")
  .select($"min", concat_ws(",", $"t3.item_code", $"t2.max", $"t3.sold_date").as("max"))
  .show(false)

这将为您提供您想要的dataframe

+------------------+------------------+
|min               |max               |
+------------------+------------------+
|101,400,11-12-2017|101,500,10-12-2017|
|201,200,10-12-2017|201,300,13-12-2017|
+------------------+------------------+

【讨论】:

  • 似乎是一个相当昂贵的过程.....即使针对 200mb 的数据集也需要大量时间。
  • 连接总是很昂贵 :)
【解决方案2】:

这里的最佳方法是为数据框创建一个新索引(即列),作为排序所需列的串联结果。在基于字符串的新索引上实现智能排序,以便结果仍然按数字排序,但您会携带 Date 的信息以及实际上您需要检索的任何内容作为查询的一部分。

这样就不需要 JOIN。

【讨论】:

    猜你喜欢
    • 2020-11-20
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 2021-04-08
    相关资源
    最近更新 更多