我有下面的三列数据框
id|visit_class|in_date
+--+-----------+--------
|1|Non Hf |24-SEP-2017
|1|Non Hf |23-SEP-2017
|1|Hf |27-SEP-2017
|1|Non Hf |28-SEP-2017
|2|Non Hf |24-SEP-2017
|2|Hf |25-SEP-2017
我想将此数据帧在id上分组,然后在indate列上对分组的数据进行排序,并且只希望第一次出现HF之后出现的那些行。输出将如下所示。意味着前2行将在id = 1时删除,而前1行将在id = 2时删除。
id|visit_class|in_date
+--+-----------+--------
|1|Hf |27-SEP-2017
|1|Non Hf |28-SEP-2017
|2|Hf |25-SEP-2017
我将如何在Spark和Scala中实现这一目标。
步骤:
1)创建WindowSpec,排序依据date
和分区依据id
:
2)创建一个累积总和以指示是否Hf
出现,然后根据条件进行过滤:
import org.apache.spark.sql.expressions.Window
val w = Window.partitionBy("id").orderBy(to_date($"in_date", "dd-MMM-yyyy"))
(df.withColumn("rn", sum(when($"visit_class" === "Hf", 1).otherwise(0)).over(w))
.filter($"rn" >= 1).drop("rn").show)
+---+-----------+-----------+
| id|visit_class| in_date|
+---+-----------+-----------+
| 1| Hf|27-SEP-2017|
| 1| Non Hf|28-SEP-2017|
| 2| Hf|25-SEP-2017|
+---+-----------+-----------+
使用spark 2.2.0to_date
并带有格式签名是2.2.0中的新功能
如果您使用的是spark <2.2.0,则可以unix_timestamp
代替使用to_date
:
val w = Window.partitionBy("id").orderBy(unix_timestamp($"in_date", "dd-MMM-yyyy"))
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句