我在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吗?我查看了窗口函数,但无法想到这样做的方法。非常感谢你。
答案 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))