在groupby spark数据帧中与条件聚合

时间:2018-09-24 10:24:48

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

我有一个数据框

id lat long lag_lat lag_long detector lag_interval  gpsdt  lead_gpsdt
  1  12   13    12       13        1        [1.5,3.5]  4      4.5
  1  12   13    12       13        1        null       4.5    5
  1  12   13    12       13        1        null       5      5.5
  1  12   13    12       13        1        null       5.5    6
  1  13   14    12       13        2        null       6      6.5
  1  13   14    13       14        2        null       6.5    null
  2  13   14    13       14        2        [0.5,1.5]  2.5    3.5  
  2  13   14    13       14        2        null       3.5    4 
  2  13   14    13       14        2        null       4      null

所以我想在agg函数中使用groupby时应用一个条件,如果我们执行groupby col(“ id”)和col(“ detector”),那么我想检查条件,如果该组中的lag_interval具有任何非-null值,然后在聚合中我希望两列是

 min("lag_interval.col1") and other is max("lead_gpsdt") 

如果不满足上述条件,那么我要

min("gpsdt"), max("lead_gpsdt")

使用这种方法,我想获取带有条件的数据

df.groupBy("detector","id").agg(first("lat-long").alias("start_coordinate"),
    last("lat-long").alias("end_coordinate"),struct(min("gpsdt"), max("lead_gpsdt")).as("interval"))

输出

  id interval  start_coordinate end_coordinate
  1   [1.5,6]      [12,13]         [13,14] 
  1   [6,6.5]      [13,14]         [13,14]
  2   [0.5,4]      [13,14]         [13,14]

**

更多说明

** 如果我们看到groupby(“ id”,“ detector”)的一部分正在淘汰,

我们必须看到,如果在那组数据中,如果col(“ lag_interval”)中的值之一不为null,则我们需要使用像这样的聚合 min(lag_interval.col1),max( lead_gpsdt) 此条件将适用于以下数据集

id lat long lag_lat lag_long detector lag_interval  gpsdt  lead_gpsdt
 1  12   13    12       13        1        [1.5,3.5]  4      4.5
 1  12   13    12       13        1        null       4.5    5
 1  12   13    12       13        1        null       5      5.5
 1  12   13    12       13        1        null       5.5    6

并且如果col(“ lag_interval”)的所有值在该组数据中为null,则需要聚合输出为 min(“ gpsdt”),max(“ lead_gpsdt”) 此条件将适用于以下数据集

id lat long lag_lat lag_long detector lag_interval  gpsdt  lead_gpsdt
 1  13   14    12       13        2        null       6      6.5
 1  13   14    13       14        2        null       6.5    null

1 个答案:

答案 0 :(得分:3)

您所遇到的条件难题应该通过使用简单的when 内置函数来解决,如下所示

import org.apache.spark.sql.functions._
df.groupBy("id","detector")
  .agg(
    struct(
      when(isnull(min("lag_interval.col1")), min("gpsdt")).otherwise(min("lag_interval.col1")).as("min"),
      max("lead_gpsdt").as(("max"))
    ).as("interval")
  )

应该为您提供

+---+--------+----------+
|id |detector|interval  |
+---+--------+----------+
|2  |2       |[0.5, 4.0]|
|1  |2       |[6.0, 6.5]|
|1  |1       |[1.5, 6.0]|
+---+--------+----------+

我想您必须已经知道如何做first("lat-long").alias("start_coordinate"), last("lat-long").alias("end_coordinate")

我希望答案会有所帮助