Skip to content Skip to sidebar Skip to footer

Spark-sql Window Functions On Dataframe - Finding First Timestamp In A Group

I have below dataframe (say UserData). uid region timestamp a 1 1 a 1 2 a 1 3 a 1 4 a 2 5 a 2 6 a 2 7 a 3 8 a 4 9 a 4 10 a 4 11 a 4

Solution 1:

Window functions are indeed useful although your approach can work only if you assume that user visits given region only once. Also window definition you use is incorrect - multiple calls to partitionBy simply return new objects with different window definitions. If you want to partition by multiple columns you should pass them in a single call (.partitionBy("region", "uid")).

Lets start with marking continuous visits in each region:

import org.apache.spark.sql.functions.{lag, sum, not}
import org.apache.spark.sql.expressions.Window 

valw= Window.partitionBy($"uid").orderBy($"timestamp")

valchange= (not(lag($"region", 1).over(w) <=> $"region")).cast("int")
valind= sum(change).over(w)

valdfWithInd= df.withColumn("ind", ind)

Next you we simply aggregate over the groups and find leads:

import org.apache.spark.sql.functions.{lead, coalesce}

valregionTimeEnd= coalesce(lead($"timestamp", 1).over(w), $"max_")

valresult= dfWithInd
  .groupBy($"uid", $"region", $"ind")
  .agg(min($"timestamp").alias("timestamp"), max($"timestamp").alias("max_"))
  .drop("ind")
  .withColumn("regionTimeEnd", regionTimeEnd)
  .withColumnRenamed("timestamp", "regionTimeStart")
  .drop("max_")

result.show

// +---+------+---------------+-------------+// |uid|region|regionTimeStart|regionTimeEnd|// +---+------+---------------+-------------+// |  a|     1|              1|            5|// |  a|     2|              5|            8|// |  a|     3|              8|            9|// |  a|     4|              9|           13|// |  a|     1|             13|           15|// |  a|     3|             15|           17|// |  a|     5|             17|           20|// +---+------+---------------+-------------+

Post a Comment for "Spark-sql Window Functions On Dataframe - Finding First Timestamp In A Group"