如何在 PySpark 中安全拼接包含 NULL 值的数组列(如 array)

本文详解如何使用 `array()` 函数替代空字符串字面量,正确实现两个 array 类型列的拼接,避免因 null 值导致整列结果为 null 的问题。

在 PySpark 中,对 array 类型列执行 concat() 操作时,若任一输入列为 NULL,整个拼接结果将自动变为 NULL——这是 Spark 的默认行为(即“NULL 传染性”)。例如,当 country 列有值 [{US, 2025-01-08}] 而 reference 为 NULL 时,直接 concat(country, reference) 会返回 NULL,而非期望的原 country 数组。

根本原因在于:coalesce() 要求所有参数类型严格一致。若尝试用 lit("")(字符串)作为 coalesce(col("reference"), lit("")) 的备选值,会触发类型不匹配错误:ARRAY> 与 STRING 无法共存于同一 coalesce 表达式中。

✅ 正确解法是:用 array() 函数生成一个空数组(类型为 ARRAY>),作为 coalesce 的第二参数,确保类型兼容:

from pyspark.sql import functions as F

result_df = joined_df.select(
    "id",
    F.concat(
        "country",
        F.coalesce("reference", F.array())  # ✅ 返回同类型空数组,非字符串
    ).alias("concatenated_column")
)
? 补充说明:F.array() 默认生成空数组 [],其数据类型由上下文自动推断为与 reference 一致(即 array),因此可安全参与 coalesce 和 concat。

? 进阶建议:若需进一步健壮性(例如两列均为 NULL 时返回空数组而非 NULL),可嵌套处理:

F.concat(
    F.coalesce("country", F.array()),
    F.coalesce("reference", F.array())
)

⚠️ 注意事项:

  • 不要使用 lit([]) 或 lit(None) —— 它们无法被 Spark 正

    确解析为数组类型;
  • 避免 F.coalesce("reference", F.array().cast(...)) 显式 cast,通常无需且易出错;
  • array() 是零参数函数,不可传入空字符串或 None,否则报错。

最终输出将严格符合预期:

+---+------------------------------------------+
| id|concatenated_column                       |
+---+------------------------------------------+
|  1|[{"US","2025-01-08"},{"UK","2025-01-08"}] |
|  2|[{"US","2025-01-08"}]                      |
+---+------------------------------------------+

此方案简洁、类型安全、无需 UDF,是处理数组列 NULL 拼接的标准实践。