Pyspark-对于每个ID,我希望过滤在两个ID的匹配数据之后出现的数据

Pyspark-对于每个ID,我希望过滤在两个ID的匹配数据之后出现的数据,pyspark,Pyspark,免责声明:我对pyspark非常陌生 以下是一个例子: 原始数据集 +----------+--------------------+---+----+ |install_id|influencer_date_time|id1|id2 | +----------+--------------------+---+----+ | 68483732| 2020-05-28 22:56:43|21 | 543| | 68483732| 2020-05-28 23:21:53|35 | 231|

免责声明:我对pyspark非常陌生

以下是一个例子:

原始数据集

+----------+--------------------+---+----+
|install_id|influencer_date_time|id1|id2 | 
+----------+--------------------+---+----+
|  68483732| 2020-05-28 22:56:43|21 | 543|
|  68483732| 2020-05-28 23:21:53|35 | 231|
|  68483732| 2020-05-29 00:03:21|23 | 23 |
|  68483732| 2020-05-29 00:05:21|54 | 654|
|  68486103| 2020-06-01 00:37:38|23 | 234|
|  68486103| 2020-06-01 00:59:30|12 | 14 |
|  68486103| 2020-06-01 01:59:30|54 | 54 |
+----------+--------------------+---+----+
我的所有数据都按安装id和影响者日期时间升序排序

过滤条件:

对于每个安装id,查找id1和id2相同的位置 对于每个安装id,删除上面找到的行之后的任何行。 在上面的示例中,对于install_id 68483732,第三行中的id1和id2相同。因此,我们需要删除第4行

对于install_id 68486103,它将保持原样,因为在具有匹配id1和id2的行之后没有出现行

以下是最终数据集的外观:

+----------+--------------------+---+----+
|install_id|influencer_date_time|id1|id2 | 
+----------+--------------------+---+----+
|  68483732| 2020-05-28 22:56:43|21 | 543|
|  68483732| 2020-05-28 23:21:53|35 | 231|
|  68483732| 2020-05-29 00:03:21|23 | 23 |
|  68486103| 2020-06-01 00:37:38|23 | 234|
|  68486103| 2020-06-01 00:59:30|12 | 12 |
|  68486103| 2020-06-01 01:59:30|54 | 54 |
+----------+--------------------+---+----+

如果您有任何帮助,我们将不胜感激。

请在比较后尝试带窗口的滞后功能

import pyspark.sql.functions as F
from pyspark.sql.window import Window
#Test data
tst = sqlContext.createDataFrame([(1,2,3,4),(1,3,4,1),(1,4,5,5),(1,6,7,8),(2,1,9,2),(2,2,9,9)],schema=['col1','col2','id1','id2'])
w = Window.partitionBy('col1').orderBy('col2')
tst_cmp = tst.withColumn("cmp",F.when(F.col('id1')==F.col('id2'),1).otherwise(0))
#%%
tst_flag = tst_cmp.withColumn("flag", F.sum(F.lag('cmp',default=0).over(w)).over(w))
tst_res = tst_flag.where(F.col('flag')==0)

比较后,使用窗口尝试滞后功能

import pyspark.sql.functions as F
from pyspark.sql.window import Window
#Test data
tst = sqlContext.createDataFrame([(1,2,3,4),(1,3,4,1),(1,4,5,5),(1,6,7,8),(2,1,9,2),(2,2,9,9)],schema=['col1','col2','id1','id2'])
w = Window.partitionBy('col1').orderBy('col2')
tst_cmp = tst.withColumn("cmp",F.when(F.col('id1')==F.col('id2'),1).otherwise(0))
#%%
tst_flag = tst_cmp.withColumn("flag", F.sum(F.lag('cmp',default=0).over(w)).over(w))
tst_res = tst_flag.where(F.col('flag')==0)
另一种选择-

用scala编写

加载测试数据 val数据= |安装|影响者|日期|时间| id1 | id2 | 68483732| 2020-05-28 22:56:43|21 | 543 | 68483732| 2020-05-28 23:21:53|35 | 231 | 68483732| 2020-05-29 00:03:21|23 | 23 | 68483732| 2020-05-29 00:05:21|54 | 654 | 68483732| 2020-05-29 00:06:21|12 | 12 | 68483732| 2020-05-29 00:07:21|54 | 654 | 68486103| 2020-06-01 00:37:38|23 | 234 | 68486103| 2020-06-01 00:59:30|12 | 14 | 68486103| 2020-06-01 01:59:30|54 | 54 .条纹边缘 val stringDS=data.splitSystem.lineSeparator .map|.split\\|.map|.replaceAll^[\t]+|[\t]+$,.mkString, .toSeq.toDS val df=spark.read .选项SEP, .optioninferSchema,对 .optionheader,true .optionnullValue,null .csvstringDS df.showfalse 打印模式 /** * +-----+----------+--+--+ *|安装|影响者|日期|时间| id1 | id2| * +-----+----------+--+--+ * |68483732 |2020-05-28 22:56:43 |21 |543| * |68483732 |2020-05-28 23:21:53 |35 |231| * |68483732 |2020-05-29 00:03:21 |23 |23 | * |68483732 |2020-05-29 00:05:21 |54 |654| * |68483732 |2020-05-29 00:06:21 |12 |12 | * |68483732 |2020-05-29 00:07:21 |54 |654| * |68486103 |2020-06-01 00:37:38 |23 |234| * |68486103 |2020-06-01 00:59:30 |12 |14 | * |68486103 |2020-06-01 01:59:30 |54 |54 | * +-----+----------+--+--+ * *根 *|-install_id:integer nullable=true *|-influencer_date_time:timestamp nullable=true *|-id1:integer nullable=true *|-id2:integer nullable=true */ 在组中首次匹配id1和id2后删除行 val w=Window.partitionByinstall\u id.orderByinfluencer\u date\u time .rowsbetween Window.unboundedprecing,Window.unboundedFollowing df.withColumnnew\u col,minwhen$id1===$id2,$influencer\u date\u time.overv .filter$influencer\u date\u time.castlong-$new\u col.castlong另一种选择-

用scala编写

加载测试数据 val数据= |安装|影响者|日期|时间| id1 | id2 | 68483732| 2020-05-28 22:56:43|21 | 543 | 68483732| 2020-05-28 23:21:53|35 | 231 | 68483732| 2020-05-29 00:03:21|23 | 23 | 68483732| 2020-05-29 00:05:21|54 | 654 | 68483732| 2020-05-29 00:06:21|12 | 12 | 68483732| 2020-05-29 00:07:21|54 | 654 | 68486103| 2020-06-01 00:37:38|23 | 234 | 68486103| 2020-06-01 00:59:30|12 | 14 | 68486103| 2020-06-01 01:59:30|54 | 54 .条纹边缘 val stringDS=data.splitSystem.lineSeparator .map|.split\\|.map|.replaceAll^[\t]+|[\t]+$,.mkString, .toSeq.toDS val df=spark.read .选项SEP, .optioninferSchema,对 .optionheader,true .optionnullValue,null .csvstringDS df.showfalse 打印模式 /** * +-----+----------+--+--+ *|安装|影响者|日期|时间| id1 | id2| * +-----+----------+--+--+ * |68483732 |2020-05-28 22:56:43 |21 |543| * |68483732 |2020-05-28 23:21:53 |35 |231| * |68483732 |2020-05-29 00:03:21 |23 |23 | * |68483732 |2020-05-29 00:05:21 |54 |654| * |68483732 |2020-05-29 00:06:21 |12 |12 | * |68483732 |2020-05-29 00:07:21 |54 |654| * |68486103 |2020-06-01 00:37:38 |23 |234| * |68486103 |2020-06-01 00:59:30 |12 |14 | * |68486103 |2020-06-01 01:59:30 |54 |54 | * +-----+----------+--+--+ * *根 *|-install_id:integer nullable=true *|-influencer_date_time:timestamp nullable=true *|-id1:integer nullable=true *|-id2:integer nullable=true */ 在组中首次匹配id1和id2后删除行 val w=Window.partitionByinstall\u id.orderByinfluencer\u date\u time .rowsbetween Window.unboundedprecing,Window.unboundedFollowing df.withColumnnew_col,minwhen$id1=== $id2,$influencer\u date\u time.over

.filter$influencer\u date\u time.castlong-$new\u col.castlong输出中是否应该有id1=54和id2=54?它遵循id1=12和id2=12,对吗?我已经添加了额外的细节。如果仍然不清楚,请告诉我。@Raghu-有一个拼写错误,现在应该有意义了。您正确地解释了逻辑。您有机会尝试任何答案吗?id1=54和id2=54是否应该出现在输出中?它遵循id1=12和id2=12,对吗?我已经添加了额外的细节。如果仍然不清楚,请告诉我。@Raghu-有一个拼写错误,现在应该有意义了。您正确地解释了逻辑。您有机会尝试任何答案吗?如果匹配行之后有多行可用,则此操作无效。目标是删除匹配行之后的所有行?啊,这是一个难题。。那么这就行不通了,谢谢你的提示。@ShubhamJain-已经更新了逻辑。。现在该工作了。。再次感谢如果匹配行之后有多行可用,则此操作将不起作用。目标是删除匹配行之后的所有行?啊,这是一个难题。。那么这就行不通了,谢谢你的提示。@ShubhamJain-已经更新了逻辑。。现在该工作了。。再次感谢。如果在匹配行之后有多行可用,那么这将不起作用,因为您使用的是无界的以下内容。这是作者的问题,如果有多个匹配的id1和id2,该怎么办。我们是应该取第一行并删除之后的所有行,还是应该取最后一行并删除之后的行?答案很好…使用datetime进行筛选很好..:如果在匹配行之后有多行可用,这将不起作用,因为您使用的是无界的以下内容,那么这是作者的问题,如果有多个匹配的id1和id2会怎么样。我们是应该取第一行并删除之后的所有行,还是应该取最后一行并删除之后的行?答案很好…使用datetime进行筛选很好..: