Pyspark 如何在保留最新数据的同时删除spark数据帧中的重复项?

Pyspark 如何在保留最新数据的同时删除spark数据帧中的重复项?,pyspark,apache-spark-sql,Pyspark,Apache Spark Sql,我使用spark从AmazonS3加载json文件。我想删除数据帧中保留最新数据的两列的重复项(我有timestamp列)。最好的方法是什么?请注意,副本可能分布在各个分区中。我可以删除保留最后一条记录的重复项而不进行洗牌吗?我正在处理1 TB的数据 我在考虑用这两列对数据帧进行分区,这样所有重复记录都将“一致地散列”到同一个分区中,因此分区级别排序后的drop duplicates将消除所有重复,只保留一个。我不知道这是否可能。非常感谢您提供任何信息。使用行编号()窗口功能可能更容易完成您的任

我使用spark从AmazonS3加载json文件。我想删除数据帧中保留最新数据的两列的重复项(我有timestamp列)。最好的方法是什么?请注意,副本可能分布在各个分区中。我可以删除保留最后一条记录的重复项而不进行洗牌吗?我正在处理1 TB的数据

我在考虑用这两列对数据帧进行分区,这样所有重复记录都将“一致地散列”到同一个分区中,因此分区级别排序后的drop duplicates将消除所有重复,只保留一个。我不知道这是否可能。非常感谢您提供任何信息。

使用行编号()窗口功能可能更容易完成您的任务,下面的
c1
是时间戳列,
c2
c3
是用于划分数据的列:

from pyspark.sql import Window, functions as F

# create a win spec which is partitioned by c2, c3 and ordered by c1 in descending order
win = Window.partitionBy('c2', 'c3').orderBy(F.col('c1').desc())

# set rn with F.row_number() and filter the result by rn == 1
df_new = df.withColumn('rn', F.row_number().over(win)).where('rn = 1').drop('rn')
df_new.show()
编辑:

如果只需要重复项并删除唯一行,请添加另一个字段:

from pyspark.sql import Window, functions as F

# create a win spec which is partitioned by c2, c3 and ordered by c1 in descending order
win = Window.partitionBy('c2', 'c3').orderBy(F.col('c1').desc())

# window to cover all rows in the same partition
win2 = Window.partitionBy('c2', 'c3') \
             .rangeBetween(Window.unboundedPreceding, Window.unboundedFollowing)

# set new columns: rn, cnt and filter the result by rn == 1 and cnt > 1
df_new = df.withColumn('rn', F.row_number().over(win)) \
           .withColumn('cnt', F.count('c1').over(win2)) \
           .where('rn = 1 and cnt > 1') \
           .drop('rn', 'cnt')
df_new.show()

我删除了我的答案,因为这将是一个更有效的没有加入!这个怎么样window=window.partitionBy(partition\u columns).orderBy(F.desc(sort\u key))`
window.partitionBy(partition\u columns).orderBy(F.asc(sort\u key))
data\u frame=data\u frame.withColumn('rank',F.rank().over(window))`
.withColumn('row\u number',F.row\u number().over(window))`
过滤器((F.col('rank')==1)和(F.col('row_number')==1)。drop('rank','row_number'))
@lalatnayak你对rank()和row_number()使用相同的窗口规范吗?我想他们在默认窗口范围内返回相同的值。谢谢你指出。实际上,我认为排名就足够了。快速提问。过滤器和并集有什么影响(使用具有不同方案的数据帧)在分区上有。@lalatnayak,不知道为什么要将数据帧与不同方案合并。你的意思是
join
?我不认为
filter
union
对分区有直接影响。这实际上取决于方法链。例如,联合(..)后面是一个独立的()。您可以尝试
explain()
,看看您的转换中是否涉及分区或洗牌。我不是这方面的专家,所以以上只是我的2美分。