Spark - 在一行数据帧内匹配状态

时间:2018-04-03 04:09:10

标签: apache-spark apache-spark-sql

下面是我的数据框架,我能够从多结构Json文件中提取和提取

-------------------------------------------
Col1  | Col2|           Col3    |   Col4
-------------------------------------------
A     |  1  |2018-03-28T19:03:39|    Active
-------------------------------------------
A     |  1  |2018-03-28T19:03:40|    Clear
-------------------------------------------
A     |  1  |2018-03-28T19:11:21|    Active
-------------------------------------------
A     |  1  |2018-03-28T20:13:06|    Active
-------------------------------------------
A     |  1  |2018-03-28T20:13:07|    Clear
-------------------------------------------

这是我通过按键分组来提出的

A|1|[(2018-03-28T19:03:39,Active),(2018-03-28T19:03:40,Clear),(2018-03-28T19:11:21,Active),(2018-03-28T20:13:06,Active),(2018-03-28T20:13:07,Clear)]

这是我想要的输出..

--------------------------------------------------------
Col1  | Col2|   Active time     |   Clear Time 
--------------------------------------------------------
A     |  1  |2018-03-28T19:03:39|    2018-03-28T19:03:40
--------------------------------------------------------
A     |  1  |2018-03-28T20:13:06|    2018-03-28T20:13:07
--------------------------------------------------------

我有点坚持这一步,不知道如何进一步获得所需的输出。任何方向都表示赞赏。

Spark版本 - 2.1.1 Scala版本 - 2.11.8

1 个答案:

答案 0 :(得分:1)

您可以使用窗口功能进行分组和排序以获得连续的有效和清除时间。因为您正在寻找为了过滤掉没有连续清除或活动状态的行,你也需要一个过滤器。

所以,如果你有dataframe

+----+----+-------------------+------+
|Col1|Col2|Col3               |Col4  |
+----+----+-------------------+------+
|A   |1   |2018-03-28T19:03:39|Active|
|A   |1   |2018-03-28T19:03:40|Clear |
|A   |1   |2018-03-28T19:11:21|Active|
|A   |1   |2018-03-28T20:13:06|Active|
|A   |1   |2018-03-28T20:13:07|Clear |
+----+----+-------------------+------+

你可以像我上面解释的那样简单地做到

import org.apache.spark.sql.expressions._
def windowSpec = Window.partitionBy("Col1", "Col2").orderBy("Col3")

import org.apache.spark.sql.functions._
df.withColumn("active", lag(struct(col("Col3"), col("Col4")), 1).over(windowSpec))
    .filter(col("active.Col4") === "Active" && col("Col4") === "Clear")
    .select(col("Col1"), col("Col2"), col("active.Col3").as("Active Time"), col("Col3").as("Clear Time"))
  .show(false)

你应该

+----+----+-------------------+-------------------+
|Col1|Col2|Active Time        |Clear Time         |
+----+----+-------------------+-------------------+
|A   |1   |2018-03-28T19:03:39|2018-03-28T19:03:40|
|A   |1   |2018-03-28T20:13:06|2018-03-28T20:13:07|
+----+----+-------------------+-------------------+