首页 > 解决方案 > Java Spark 删除重复项/空值并保留顺序

问题描述

我有以下 Java Spark 数据集/数据框。

Col_1 Col_2 Col_3 ...
A     1     1
A     1     NULL
B     2     2
B     2     3
C     1     NULL

该数据集中有近 25 列,我必须删除在 Col_1 上重复的那些记录。如果第二条记录为 NULL,则必须删除 NULL(如 COl_1 = A 的情况),如果有多个有效值,如 Col_1 = B 的情况,则只有一个有效的 Col_2 = 2 和 Col_3 = 2 应该是每次都保留。如果只有一条带有 null 的记录,例如 Col_1 = C 的情况,则必须保留它

预期输出:

Col_1 Col_2 Col_3 ...
A     1     1
B     2     2
C     1     NULL

到目前为止我尝试了什么:

我尝试使用 group by 并使用 sort_array 和 array_remove 收集集合,但即使只有一行,它也会完全删除空值。

如何在 Java Spark 中实现预期的输出。

标签: javaapache-spark

解决方案


这是使用 spark 数据帧的方法:

import org.apache.spark.sql.functions.{coalesce, col, lit, min, struct}

val rows = Seq(
  ("A",1,Some(1)),
  ("A",1, Option.empty[Int]),
  ("B",2,Some(2)),
  ("B",2,Some(3)),
  ("C",1,Option.empty[Int]))
  .toDF("Col_1", "Col_2", "Col_3")

rows.show()

+-----+-----+-----+
|Col_1|Col_2|Col_3|
+-----+-----+-----+
|    A|    1|    1|
|    A|    1| null|
|    B|    2|    2|
|    B|    2|    3|
|    C|    1| null|
+-----+-----+-----+

val deduped = rows.groupBy(col("Col_1"))
  .agg(
    min(
      struct(
        coalesce(col("Col_3"), lit(Int.MaxValue)).as("null_maxed"), 
        col("Col_2"), 
        col("Col_3"))).as("argmax"))
  .select(col("Col_1"), col("argmax.Col_2"), col("argmax.Col_3"))

deduped.show()

+-----+-----+-----+
|Col_1|Col_2|Col_3|
+-----+-----+-----+
|    B|    2|    2|
|    C|    1| null| 
|    A|    1|    1|
+-----+-----+-----+

这里发生的事情是您正在分组Col_1,然后获得复合结构的最小值,Col_3但其中的Col_2空值Col_3已被最大整数值替换,因此它们不会影响排序。然后我们从结果行中选择原始Col_3和。Col_2我意识到这是在 scala 中,但 java 的语法应该非常相似。


推荐阅读