Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 时间窗口中的Spark数据帧变换_Scala_Apache Spark_Spark Dataframe_Emr - Fatal编程技术网

Scala 时间窗口中的Spark数据帧变换

Scala 时间窗口中的Spark数据帧变换,scala,apache-spark,spark-dataframe,emr,Scala,Apache Spark,Spark Dataframe,Emr,我有两个数据帧。[AllAccounts]:包含对所有用户的所有帐户的审核 UserId, AccountId, Balance, CreatedOn 1, acc1, 200.01, 2016-12-06T17:09:36.123-05:00 1, acc2, 189.00, 2016-12-06T17:09:38.123-05:00 1, acc1, 700.01, 2016-12-07T17:09:36.123-05:00 1, acc2, 189.00, 2016-12-07T17:

我有两个数据帧。[AllAccounts]:包含对所有用户的所有帐户的审核

UserId, AccountId, Balance, CreatedOn
1, acc1, 200.01, 2016-12-06T17:09:36.123-05:00
1, acc2, 189.00, 2016-12-06T17:09:38.123-05:00  
1, acc1, 700.01, 2016-12-07T17:09:36.123-05:00
1, acc2, 189.00, 2016-12-07T17:09:38.123-05:00
1, acc3, 010.01, 2016-12-07T17:09:39.123-05:00
1, acc1, 900.01, 2016-12-08T17:09:36.123-05:00
[ActiveAccounts]:仅包含对任何用户的活动帐户(可以是零或1)的审核

UserId, AccountId, CreatedOn
1, acc2, 189.00, 2016-12-06T17:09:38.123-05:00
1, acc3, 010.01, 2016-12-07T17:09:39.123-05:00
我想把它们转换成一个DF格式

UserId, AccountId, Balance, CreatedOn, IsActive
1, acc1, 200.01, 2016-12-06T17:09:36.123-05:00, false
1, acc2, 189.00, 2016-12-06T17:09:38.123-05:00, true 
1, acc1, 700.01, 2016-12-07T17:09:36.123-05:00, false
1, acc2, 189.00, 2016-12-07T17:09:38.123-05:00, true
1, acc3, 010.01, 2016-12-07T17:09:39.123-05:00, true
1, acc1, 900.01, 2016-12-08T17:09:36.123-05:00, false
因此,根据ActiveAccounts中的帐户,我需要适当地标记第一个df中的行。如示例中所示,用户ID 1的acc2在2016-12-06T17:09:38.123-05:00标记为活动,acc3在2016-12-07T17:09:39.123-05:00标记为活动。顺便说一句,这些时间范围acc2将被标记为真,2016-12-07T17:09:39以后的acc3将被标记为真


如果我正确理解帐户
(1,acc1)
在其创建时间和
(1,acc2)
的创建时间之间处于活动状态,那么什么是有效的方法。

我们可以通过几个步骤来实现这一点:

  • 创建包含每个帐户的开始/结束时间的数据框
  • 加入
    AllAccounts
  • 标记结果数据帧的行
我还没有测试过这个,所以可能有语法错误

为了完成第一个任务,我们需要按
user
对数据帧进行分区,然后查看下一个创建时间。这需要一个窗口函数:

val window = Window.partitionBy("UserId").orderBy("StartTime")
val activeTimes = ActiveAccounts.withColumnRenamed("CreatedOn", "StartTime")
  .withColumn("EndTime", lead("StartTime") over window)
请注意,每个用户的最后一次
EndTime
将为
null
。现在加入:

val withActive = AllAcounts.join(activeTimes, Seq("UserId", "AccountId"))
(如果您可能缺少某些帐户的活动时间,则此连接应为左连接。)

然后,您必须检查并将帐户标记为活动帐户:

val withFlags = withActive.withColumn("isActive",
  $"CreatedOn" >= $"StartTime" && 
 ($"EndTime".isNull || ($"CreatedOn" < $"EndTime)))
val-withFlags=withActive.withColumn(“isActive”,
$“CreatedOn”>=$“StartTime”和
($“EndTime”.isNull | |($“CreatedOn”<$“EndTime)))

您可以编写一个
UDF
来执行此操作。