在火花数组列中爆炸到多列火花sql

Posted

技术标签:

【中文标题】在火花数组列中爆炸到多列火花sql【英文标题】:explode an spark array column to multiple columns sparksql 【发布时间】:2020-09-13 13:10:27 【问题描述】:

我有一个类型为 Value 的列,定义如下

val Value: ArrayType = ArrayType(
  new StructType()
  .add("unit", StringType)
  .add("value", StringType)
)

还有这样的数据

[[unit1, 25], [unit2, 77]]
[[unit2, 100], [unit1, 40]]
[[unit2, 88]]
[[unit1, 33]]

我知道 spark sql 可以使用 functions.explode 使数据变为多行,但我想要的是分解为多列(或 1 个一列但 2 个项目只有 1 个项目)。

所以最终结果如下所示

unit1 unit2
25  77
40  100
value1 88
33 value2

我怎样才能做到这一点?

添加在初次发布和更新后 我想得到这样的结果(这更像是我的最终目标)。

transformed-column
[[unit1, 25], [unit2, 77]]
[[unit2, 104], [unit1, 40]]
[[unit1, value1], [unit2, 88]]
[[unit1, 33],[unit2,value2]]

其中value1 是使用[unit2, 88] 应用某种映射/转换函数的结果 同样,value2 是使用 [unit1, 33] 应用相同的映射 /conversion 函数的结果

【问题讨论】:

结果数据的第二行是如何计算的?数组总是只有 1 或 2 个元素还是可能有更多? @Minnie,预期的结果不应该类似于(unit1, unit2): (25, 27), (40, 100), (null, 88), (33, null)吗? 嗨@werner,它是1 或2 项。不能更多。在仔细阅读了您和 LeoC 所说的内容后,我才意识到我的模拟结果有误。我现在已经更新了。 嗨@LeoC,对不起,你是对的,我会更新预期的结果。 您可以使用map_from_entries将列转换为地图,然后通过键选择地图:unit1和unit2。 spark.apache.org/docs/latest/api/python/…。顺便提一句。这是一个pyspark链接,Scala应该是一样的。 【参考方案1】:

我按照@jxc的建议使用map_from_entries解决了这个问题,然后使用UDF将1项的映射转换为2项的映射,使用业务逻辑在2个单位之间进行转换。

需要注意的是,map_from_entries 返回的地图是 scala 地图。如果您使用java,需要确保udf 方法采用scala 映射。

ps。也许我不必使用 map_from_entries,也许我可以让UDFarraystructType

【讨论】:

以上是关于在火花数组列中爆炸到多列火花sql的主要内容,如果未能解决你的问题,请参考以下文章

聚合火花数据框中的多列(所有组合)

如何替换火花数据框所有列中的多个字符?

Spark Java - 将多列收集到数组列中

火花多条件加入

Apache Spark 数据框列爆炸为多列

验证输入火花数据帧中的时间戳以生成正确的输出火花数据帧