Spark Explode of Empty Column 返回 Empty Row [重复]

Posted

技术标签:

【中文标题】Spark Explode of Empty Column 返回 Empty Row [重复]【英文标题】:Spark Explode of Empty Column returns Empty Row [duplicate] 【发布时间】:2018-09-19 17:41:41 【问题描述】:

我是 Spark 编程的新手。我正在尝试用空行分解 DataFrame 的列。我认为explode函数简单来说,为数组中的每个元素创建额外的行。但结果是不同的。

我无法理解爆炸后的 DataFrame 背后的逻辑。 有人可以解释以下示例。 我想了解这个结果的基本原理/原因。 为什么空数组在数据帧中被视为空?

//inputDataFrame
+---+------+----------+
|age|  name|occupation|
+---+------+----------+
| []|Harish| developer|
+---+------+----------+

df.withColumn("age",explode(col("age")))

//DataFrame with age column exploded
+---+----+----------+
|age|name|occupation|
+---+----+----------+
+---+----+----------+

// expected DataFrame
    +---+------+----------+     +----+------+----------+
    |age|  name|occupation|     |age |  name|occupation|
    +---+------+----------+ (or)+----+------+----------+
    |   |Harish| developer|     |null|Harish| developer|
    +---+------+----------+     +----+------+----------+

EDIT1:根据 Chandan,我发现了这个堆栈问题 Spark sql how to explode without losing null values 并且可以理解 spark2 可用的爆炸 api。但我找不到关于为什么删除该行的正确解释。

【问题讨论】:

我已经阅读了shaido提到的那个问题。我也写过问题edit1。但是由于它不能帮助我解决我的疑问,所以我提出了这个问题,至于为什么 null 对象和空数组被认为是相同的 虽然问题似乎是重复的,但我找到了 Chandan 附加的源代码链接更好的解释。每个答案都告诉我 null 对象被忽略但从未提及为什么所以我问了这个问题。很抱歉浪费您的时间,感谢您的帮助 【参考方案1】:

这就是explode api的行为。如果您想获得所需的输出,请使用explode_outer

df.withColumn("age",explode_outer(col("age")))

【讨论】:

谢谢陈丹。但我想知道这个问题的根本原因/explode 分解数组以获得额外行的机制,或者我的行被删除的原因。 爆炸功能与数据集的平面地图相同,这不是问题。 explode_outer 生成相同的输出,但唯一的区别是如果 array 或 map 为空,那么它不会忽略它,并且会为该列生成空值,而其他列就位。请查看源代码github.com/apache/spark/blob/master/sql/core/src/main/scala/org/… 感谢 Chandan,您的回答帮助很大 @HarishGontu 如果您觉得有用,请接受答案 @HarishGontuThanks

以上是关于Spark Explode of Empty Column 返回 Empty Row [重复]的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 sparkDataframe 获取 Json 列:org.apache.spark.sql.AnalysisException:无法解析 'explode;

Spark SQL 'explode' 命令在 AWS EC2 上失败,但在本地成功

Spark使用explode展开嵌套的JSON数据

php explode容易犯的错误

获取手机浏览器IP的函数

Spark Scala Error: java.lang.NoSuchMethodError: scala.collection.mutable.Buffer$.empty()Lscalacollec