Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.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
Pyspark-合并连续的重复行,但保留开始和结束日期_Pyspark_Pyspark Sql - Fatal编程技术网

Pyspark-合并连续的重复行,但保留开始和结束日期

Pyspark-合并连续的重复行,但保留开始和结束日期,pyspark,pyspark-sql,Pyspark,Pyspark Sql,我有一个以下格式的数据帧 id , name, start_date, end_date , active 1 , albert , 2019-08-14, 3499-12-31, 1 1 , albert , 2019-08-13, 2019-08-14, 0 1 , albert , 2019-06-26, 2019-08-13, 0 1 , brian , 2018-01-17, 2019-06-26, 0 1 , brian , 2017-07-31, 2

我有一个以下格式的数据帧

id , name, start_date, end_date  , active
1  , albert   , 2019-08-14, 3499-12-31, 1
1  , albert   , 2019-08-13, 2019-08-14, 0
1  , albert   , 2019-06-26, 2019-08-13, 0
1  , brian   , 2018-01-17, 2019-06-26, 0
1  , brian   , 2017-07-31, 2018-01-17, 0
1  , albert   , 2017-03-31, 2018-07-31, 0
2  , diane   , 2019-07-14, 3499-12-31, 1
2  , diane   , 2019-06-13, 2019-07-14, 0
2  , ethel   , 2019-03-20, 2019-06-13, 0
2  , ethel  , 2018-01-17, 2019-03-20, 0
2  , frank   , 2017-07-31, 2018-01-17, 0
2  , frank   , 2015-03-21, 2018-07-31, 0
我希望合并名称与前一行相同的连续行,但在最终输出数据帧中保持正确的开始和结束日期。所以正确的输出应该是

id , name, start_date, end_date  , active
1  , albert   , 2019-06-26, 3499-12-31, 1
1  , brian   , 2017-07-31, 2019-06-26, 0
1  , albert   , 2017-03-31, 2018-07-31, 0
2  , diane   , 2019-06-13, 3499-12-31, 1
2  , ethel   , 2018-01-17, 2019-06-13, 0
2  , frank   , 2017-03-31, 2018-01-17, 0
每个id的条目数不同,每个id的不同名称数也不同

如何在pyspark中实现这一点?
谢谢

您是否正在寻找
df.groupby([“名称”、“开始日期”、“结束日期”)).sum(“活动”)


如果我对你的问题理解正确,上面的代码将完成这项工作。

因此,经过一番思考,我想出了如何做到这一点。也许有更好的方法,但这是可行的

首先创建一个窗口,按id分区,按开始日期排序,并捕获下一行

frame = Window.partitionBy('id').orderBy(col('start_date').desc())
df = df.select('*', lag(col('name'), default=0).over(frame).alias('next_name'))
然后,如果当前名称行和下一个名称与集合0匹配,则选择集合1

df = df.withColumn('countrr', when(col('name') == col('next_name'), 0).otherwise(1))
接下来创建一个框架扩展,以获取窗口开始和当前行之间的行,并对框架的计数列求和

frame2 = Window.partitionBy('id').orderBy(col('start_date').desc()).rowsBetween(Window.unboundedPreceding, Window.currentRow)
df = df.withColumn('sumrr', sum('countrr').over(frame2)
这将有效地创建一个列,当名称更改时,该列将增加1。最后,您可以使用这个新的sumrr列和其他列来分组,并根据需要获取最大和最小日期

gb_df = df.groupby(['id', 'name', 'sumrr'])
result = gb_df.agg({'start_date':'min', 'end_date':'max'})
然后,您必须在id、名称和结束日期上加入活动标志


提供正确的输出…

是,但有时名称列具有相同的名称,并用不同的名称分隔。因此,假设2016年可能是a,2017年变为b,但2018年又恢复为a。然后你应该为这些名称创建一个标识符,用某种唯一的
id
标记所有相同的
名称,然后将它们添加到
groupby
调用中。