在Spark数据帧中聚合多个列

时间:2017-09-04 07:04:28

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

我在解决以下问题时遇到了问题。 基本上我想知道特定项目(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操作。

enter image description here

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

以上内容将帮助我获得音量的maxmin,但我希望它们与各自的日期一起。

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

2 个答案:

答案 0 :(得分: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|
+------------------+------------------+

答案 1 :(得分:0)

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

那样,就不需要JOIN。