如何使用条件为每个组生成新的列值

时间:2016-03-01 18:19:19

标签: scala apache-spark

我在spark中有一个数据框如下:

ID Sales

1      0  
1      0  
1      5000  
1      0    
1      0
1      2000
1      0
2      0
2      0
2      3000
2      1000
2      0
2      0

现在,我想创建第三列,对于每个ID,每个ID都以0开头,只要在Sales列中遇到严格正值,就会增加1。每当指标增加1时,我都希望重复该数字,直到行中的“销售”列遇到另一个严格正值。结果数据框如下:

ID   Sales  Indicator
1      0      0  
1      0      0
1      5000   1
1      0      1
1      0      1
1      2000   2
1      0      2
2      0      0
2      0      0
2      3000   1
2      1000   2
2      0      2
2      0      2

我怎样才能以有效的方式实现这一目标?我们可以使用mapPartitions吗?我查看了窗口函数,但无法想到这样做的方法。非常感谢你。

1 个答案:

答案 0 :(得分:1)

使用Window功能,您可以这样做:

正如Robert Horvick指出的那样,您需要某种方式来对给定ID中的行进行排序,以便结果具有确定性。我们假设您有一列OrderingCol来执行此操作,因此您的数据类似于:

ID   Sales    OrderingCol

1      0        1
1      0        2
1      5000     3
1      0        4
1      0        5
1      2000     6
1      0        7
2      0        1
2      0        2
2      3000     3
2      1000     4
2      0        5
2      0        6

当然,正如你所说,任何排序行的方法都可行(按日期等)。

然后,假设上面的数据在df

,你可以这样做
import org.apache.spark.sql.expressions._
import org.apache.spark.sql.functions._
import spark.implicits._

val ws = Window.partitionBy("ID").orderBy("OrderingCol")
val df2 = df.withColumn("Indicator", sum(when($"Sales" > 0, 1).otherwise(0)).over(ws))