Pyspark-对于每个ID,我希望过滤在两个ID的匹配数据之后出现的数据
免责声明:我对pyspark非常陌生 以下是一个例子: 原始数据集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|
+----------+--------------------+---+----+
|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进行筛选很好..: