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_Pyspark_Apache Spark Sql_Spark Dataframe - Fatal编程技术网

Scala Spark数据帧-窗口功能-滞后和;用于插入和插入的导线;更新输出

Scala Spark数据帧-窗口功能-滞后和;用于插入和插入的导线;更新输出,scala,apache-spark,pyspark,apache-spark-sql,spark-dataframe,Scala,Apache Spark,Pyspark,Apache Spark Sql,Spark Dataframe,我需要使用窗口功能Lag和Lead对数据帧执行以下操作 对于每个键,我需要在最终输出中执行以下插入和更新操作 插入条件: 1.默认情况下,层号=0需要写入输出中。 2.如果COL1、COL2、COL3的值与其珍贵记录相对应有任何变化,则需要在输出中写入该记录 示例:图层号为2的按键号为,COL3中的值从400变为600 更新条件: 1.如果COL1、COL2、COL3的值与其以前的记录相比没有变化,但“离开列”中有变化,则需要在输出中更新该值 示例:层号为3的键号为,COL1、COL2、COL3

我需要使用窗口功能Lag和Lead对数据帧执行以下操作

对于每个键,我需要在最终输出中执行以下插入和更新操作

插入条件:
1.默认情况下,层号=0需要写入输出中。
2.如果COL1、COL2、COL3的值与其珍贵记录相对应有任何变化,则需要在输出中写入该记录

示例:图层号为2的按键号为,COL3中的值从400变为600

更新条件:
1.如果COL1、COL2、COL3的值与其以前的记录相比没有变化,但“离开列”中有变化,则需要在输出中更新该值

示例:层号为3的键号为,COL1、COL2、COL3中没有更改,但DEVITE列中的值更改为“xyz”,因此需要在输出中进行更新。
2.在插入层号为0的记录后,即使层号也应按顺序更新

    val inputDF = values.toDF("KEY","LAYER_NO","COl1","COl2","COl3","DEPART")

    inputDF.show()   
    +-----+--------+----+----+----+------+
    |  KEY|LAYER_NO|COL1|COL2|COL3|DEPART|
    +-----+--------+----+----+----+------+
    |key_1|       0| 200| 300| 400|   abc|->default write
    |key_1|       1| 200| 300| 400|   abc|
    |key_1|       2| 200| 300| 600|   uil|--->change in col3,so write
    |key_1|       2| 200| 300| 600|   uil|
    |key_1|       3| 200| 300| 600|   xyz|--->change in col4,so update
    |key_2|       0| 500| 700| 900|   prq|->default write
    |key_2|       1| 888| 555| 900|   tep|--->change in col1 & col 2,so write
    |key_3|       0| 111| 222| 333|   lgh|->default write
    |key_3|       1| 084| 222| 333|   lgh|--->change in col1,so write
    |key_3|       2| 084| 222| 333|   rrr|--->change in col4,so update
    +-----+--------+----+----+----+------+
预期产出:

outputDF.show()
+-----+--------+----+----+----+------+
|  KEY|LAYER_NO|COl1|COl2|COl3|DEPART|
+-----+--------+----+----+----+------+
|key_1|       0| 200| 300| 400|   abc|
|key_1|       1| 200| 300| 600|   xyz|
|key_2|       0| 500| 700| 900|   prq|
|key_2|       1| 888| 555| 900|   tep|
|key_3|       0| 111| 222| 333|   lgh|
|key_3|       1| 084| 222| 333|   rrr|
+-----+--------+----+----+----+------+

我们需要定义两个
窗口
,以达到您的预期输出。一个用于检查
DEPART
列中的更改,第二个用于检查
COL1
COL3
之和的差异

import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions.Window

val w_col = Window.partitionBy("KEY", "COL1", "COL2", "COL3").orderBy("LAYER_NO")
                  .rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)
val w_key = Window.partitionBy("KEY").orderBy("LAYER_NO")
然后,我们只需用正确的值替换
DEPART
列中的值,并将数据过滤到滞后总和与当前列总和不同的行(以及
LAYER\u NO==0的行)。最后,我们用秩替换
层号

inputDF.withColumn("DEPART", last("DEPART").over(w_col))
   .withColumn("row_sum",($"COL1" + $"COL2" + $"COL3"))
   .withColumn("lag_sum", lag($"row_sum",1).over(w_key))
   .filter($"LAYER_NO" === 0 || not($"row_sum" === $"lag_sum"))
   .withColumn("LAYER_NO", rank.over(w_key)-1)
   .drop("row_sum", "lag_sum").show()
+-----+--------+----+----+----+------+
|  KEY|LAYER_NO|COl1|COl2|COl3|DEPART|
+-----+--------+----+----+----+------+
|key_1|       0| 200| 300| 400|   abc|
|key_1|       1| 200| 300| 600|   xyz|
|key_2|       0| 500| 700| 900|   prq|
|key_2|       1| 888| 555| 900|   tep|
|key_3|       0| 111| 222| 333|   lgh|
|key_3|       1| 084| 222| 333|   rrr|
+-----+--------+----+----+----+------+

为什么
|键1 |键2 |键200 |键300 |键600 |键uil
没有;输出中没有输入?| key|u 1 | 1 | 200 | 300 | 600 | uil |写入输出中,但在下一条记录中,deep列中有一个值更改,因此这会将“uil”更新为“xyz”。那么最终录制的是| key|u 1 | 1 | 200 | 300 | 600 | xyz |那么为什么层| u no是1呢?不是应该是3吗?很抱歉,这是信息缺失…现在更新了问题..即使是层编号也应该在插入层编号为0的记录后按顺序更新是..我还需要更新层编号。如何实现这一点?我们可以在第二个窗口中使用
rank()
,请参见更新