Spark Scala转换数据框/ rdd

时间:2019-05-23 01:16:44

标签: scala apache-spark

我有一个如下所示的CSV文件。

PK,key,Value
100,col1,val11
100,col2,val12
100,idx,1
100,icol1,ival11
100,icol3,ival13
100,idx,2
100,icol1,ival21
100,icol2,ival22
101,col1,val21
101,col2,val22
101,idx,1
101,icol1,ival11
101,icol3,ival13
101,idx,3
101,icol1,ival31
101,icol2,ival32

我想将其转换为以下内容。

PK,idx,key,Value
100,,col1,val11
100,,col2,val12
100,1,idx,1
100,1,icol1,ival11
100,1,icol3,ival13
100,2,idx,2
100,2,icol1,ival21
100,2,icol2,ival22
101,,col1,val21
101,,col2,val22
101,1,idx,1
101,1,icol1,ival11
101,1,icol3,ival13
101,3,idx,3
101,3,icol1,ival31
101,3,icol2,ival32

基本上,我想在输出数据框中创建一个名为idx的新列,该列将填充与key = idx,value =“ n”之后的行相同的值“ n”。

1 个答案:

答案 0 :(得分:1)

这是将last窗口函数与Spark> = 2.0.0结合使用的一种方法:

import org.apache.spark.sql.functions.{last, when, lit}
import org.apache.spark.sql.expressions.Window

val w = Window.partitionBy("PK").rowsBetween(Window.unboundedPreceding, 0)

df.withColumn("idx", when($"key" === lit("idx"), $"Value"))
  .withColumn("idx", last($"idx", true).over(w))
  .orderBy($"PK")
  .show

输出:

+---+-----+------+----+
| PK|  key| Value| idx|
+---+-----+------+----+
|100| col1| val11|null|
|100| col2| val12|null|
|100|  idx|     1|   1|
|100|icol1|ival11|   1|
|100|icol3|ival13|   1|
|100|  idx|     2|   2|
|100|icol1|ival21|   2|
|100|icol2|ival22|   2|
|101| col1| val21|null|
|101| col2| val22|null|
|101|  idx|     1|   1|
|101|icol1|ival11|   1|
|101|icol3|ival13|   1|
|101|  idx|     3|   3|
|101|icol1|ival31|   3|
|101|icol2|ival32|   3|
+---+-----+------+----+

代码首先创建一个名为idx的新列,当Value时包含key == idx的值,否则返回null。然后,它在定义的窗口上检索观察到的last idx