根据组列删除列中的空值

Delete null values in a column based on a group column

我有一个包含组、ID 和目标列的数据集。我试图通过组列消除空目标值,忽略 ID 列。我想在 PySpark 中执行此操作。

| Group | ID  | Target   |
| ----- | --- | -------- |
| A     | B   |  10      |
| A     | B   |  10      |
| A     | B   |  10      |
| A     | C   | null     |
| A     | C   | null     |
| A     | C   | null     |
| B     | D   | null     |
| B     | D   | null     |
| B     | D   | null     |

这是我正在寻找的结果数据集:

| Group | ID  | Target   |
| ----- | --- | -------- |
| A     | B   |  10      |
| A     | B   |  10      |
| A     | B   |  10      | 
| B     | D   | null     |
| B     | D   | null     |
| B     | D   | null     |

换句话说,如果该组已经有一个目标值,我不需要该组中具有空目标的值,无论它们的 ID 是什么。但是,我需要确保每个组都有一个不为空的目标,所以如果有一个只有空目标的组,它们就不能被删除。

您可以为每个组计算 max(target),并将其分配给组中的所有行。然后过滤行,如果最大值为空,则 select 如果最大值不为空且目标也不为空,则该行为


from pyspark.sql import functions as F
from pyspark.sql import Window

data = [("A", "B", 10),
 ("A", "B", 10),
 ("A", "B", 10),
 ("A", "C", None),
 ("A", "C", None),
 ("A", "C", None),
 ("B", "D", None),
 ("B", "D", None),
 ("B", "D", None),]

df = spark.createDataFrame(data, ("Group", "ID", "Target",))


window_spec = Window.partitionBy("Group")

df.withColumn("max_target", F.max("Target").over(window_spec))\
  .filter((F.col("max_target").isNull()) | 
          (F.col("Target").isNotNull() & F.col("max_target").isNotNull()))\
  .drop("max_target")\
  .show()

输出

+-----+---+------+
|Group| ID|Target|
+-----+---+------+
|    A|  B|    10|
|    A|  B|    10|
|    A|  B|    10|
|    B|  D|  null|
|    B|  D|  null|
|    B|  D|  null|
+-----+---+------+