Apache spark Pyspark:计算连续观测的条纹

Apache spark Pyspark:计算连续观测的条纹,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我有一个Spark(2.4.0)数据框,其中一列只有两个值(要么0要么1)。我需要计算此数据中连续0s和1s的条纹,如果值发生变化,则将条纹重置为零 例如: 从pyspark.sql导入(SparkSession,窗口) 从pyspark.sql.functions导入(到日期、行号、前导、列) spark=SparkSession.builder.appName('test').getOrCreate() #创建数据帧 df=spark.createDataFrame([ ('2018-01-

我有一个Spark(2.4.0)数据框,其中一列只有两个值(要么
0
要么
1
)。我需要计算此数据中连续
0
s和
1
s的条纹,如果值发生变化,则将条纹重置为零

例如:

从pyspark.sql导入(SparkSession,窗口)
从pyspark.sql.functions导入(到日期、行号、前导、列)
spark=SparkSession.builder.appName('test').getOrCreate()
#创建数据帧
df=spark.createDataFrame([
('2018-01-01','John',0,0),
('2018-01-01','Paul',1,0),
('2018-01-08','Paul',3,1),
('2018-01-08','Pete',4,0),
('2018-01-08','John',3,0),
('2018-01-15','Mary',6,0),
('2018-01-15','Pete',6,0),
('2018-01-15','John',6,1),
('2018-01-15','Paul',6,1),
],['str_date','name','value','flag'])
df.orderBy('name','str_date').show()
## +----------+----+-----+----+
##| str|u日期|名称|值|标志|
## +----------+----+-----+----+
##| 2018-01-01 |约翰| 0 | 0|
##| 2018-01-08 |约翰| 3 | 0|
##| 2018-01-15 |约翰| 6 | 1|
##| 2018-01-15 |玛丽| 6 | 0|
##| 2018-01-01 |保罗| 1 | 0|
##| 2018-01-08 |保罗| 3 | 1|
##| 2018-01-15 |保罗| 6 | 1|
##| 2018-01-08 |皮特| 4 | 0|
##| 2018-01-15 |皮特| 6 | 0|
## +----------+----+-----+----+
有了这些数据,我想计算连续0和1的条纹,按日期排序,按名称“开窗”:

#预期结果:
## +----------+----+-----+----+--------+--------+
##| stru|u date | name | value | flag | streak|u 0 | streak|u 1|
## +----------+----+-----+----+--------+--------+
##| 2018-01-01 |约翰| 0 | 0 | 1 | 0|
##| 2018-01-08 |约翰| 3 | 0 | 2 | 0|
##| 2018-01-15 |约翰| 6 | 1 | 0 | 1|
##| 2018-01-15 |玛丽| 6 | 0 | 1 | 0|
##| 2018-01-01 |保罗| 1 | 0 | 1 | 0|
##| 2018-01-08 |保罗| 3 | 1 | 0 | 1|
##| 2018-01-15 |保罗| 6 | 1 | 0 | 2|
##| 2018-01-08 |皮特| 4 | 0 | 1 | 0|
##| 2018-01-15 |皮特| 6 | 0 | 2 | 0|
## +----------+----+-----+----+--------+--------+
当然,如果“标志”改变,我需要条纹将自身重置为零


有没有办法做到这一点?

这需要采用行号差异法,首先将具有相同值的连续行分组,然后在各组之间使用排名法

from pyspark.sql import Window 
from pyspark.sql import functions as f
#Windows definition
w1 = Window.partitionBy(df.name).orderBy(df.date)
w2 = Window.partitionBy(df.name,df.flag).orderBy(df.date)

res = df.withColumn('grp',f.row_number().over(w1)-f.row_number().over(w2))
#Window definition for streak
w3 = Window.partitionBy(res.name,res.flag,res.grp).orderBy(res.date)
streak_res = res.withColumn('streak_0',f.when(res.flag == 1,0).otherwise(f.row_number().over(w3))) \
                .withColumn('streak_1',f.when(res.flag == 0,0).otherwise(f.row_number().over(w3)))
streak_res.show()

假设
paul
2018-01-20
上有一个标志
0
。你希望
strike_0
是2还是1?@VamsiPrabhala罢工将是1,因为需要重置strike