如何基于自定义逻辑在Spark数据框中删除重复行?

时间:2020-09-18 02:38:57

标签: scala apache-spark apache-spark-sql

我有一个Spark数据框,其外观如下:

Id,timestamp,index,target
id1,2020-04-03,1,34
id1,2020-04-03,2,37
id1,2020-04-04,1,31
id1,2020-04-05,1,29
id2,2020-04-03,1,35
...

数据框在“ Id”列上的群集中进行了分区。

我要确保不存在重复值“ Id”和“ timestamp”的行。
如果存在重复的条目,那么我想选择“ index”值较低的行。
(如果重复的行在“ Id”,“ timestamp”,“ index”中具有相同的条目,则可以选择任何行)

因此,重复数据删除后的上方数据帧应如下所示:

Id,timestamp,index,target
id1,2020-04-03,1,34
id1,2020-04-04,1,31
id1,2020-04-05,1,29
id2,2020-04-03,1,35
...

请注意,第二行已删除。

由于数据帧已经在“ Id”上进行了分区-我希望找到一种无需跨分区进行通信的方式,从而使操作非常有效。

1 个答案:

答案 0 :(得分:0)

val df = Seq(
  ("id1", "2020-04-03", "2", "34"),
  ("id1", "2020-04-03", "3", "34"),
  ("id1", "2020-04-03", "1", "37"),
  ("id1", "2020-04-03", "5", "34"),
  ("id1", "2020-04-04", "1", "31"),
  ("id1", "2020-04-05", "1", "29"),
  ("id2", "2020-04-03", "1", "35")).toDF("Id", "timestamp", "index", "target")

df.sort("index").dropDuplicates("Id", "timestamp").orderBy("timestamp").show()
+---+----------+-----+------+
| Id| timestamp|index|target|
+---+----------+-----+------+
|id1|2020-04-03|    1|    37|
|id2|2020-04-03|    1|    35|
|id1|2020-04-04|    1|    31|
|id1|2020-04-05|    1|    29|
+---+----------+-----+------+

您可以按索引排序,然后使用删除重复项来实现并保持较低的索引。