横向视图/在 Spark 中用多列爆炸,得到重复

Posted

技术标签:

【中文标题】横向视图/在 Spark 中用多列爆炸,得到重复【英文标题】:Lateral view / explode in Spark with multiple columns, getting duplicates 【发布时间】:2019-05-21 16:22:37 【问题描述】:

我有以下数据框,其中包含一些包含数组的列。 (我们使用的是 spark 1.6)

+--------------------+--------------+------------------+--------------+--------------------+-------------+
|            UserName|     col1     |    col2          |col3          |col4                |col5         |
+--------------------+--------------+------------------+--------------+--------------------+-------------+
|foo                 |[Main, Indi...|[1777203, 1777203]|    [GBP, GBP]|            [CR, CR]|   [143, 143]|
+--------------------+--------------+------------------+--------------+--------------------+-------------+

我希望得到以下结果:

+--------------------+--------------+------------------+--------------+--------------------+-------------+
|            UserName|     explod   |    explod2       |explod3       |explod4             |explod5      |
+--------------------+--------------+------------------+--------------+--------------------+-------------+
|NNNNNNNNNNNNNNNNN...|      Main    |1777203           |    GBP      |     CR              |    143      |
|NNNNNNNNNNNNNNNNN...|Individual    |1777203           |    GBP      |     CR              |    143      |
----------------------------------------------------------------------------------------------------------

我尝试了横向视图:

sqlContext.sql("SELECT `UserName`, explod, explod2, explod3, explod4, explod5 FROM sourceDF
LATERAL VIEW explode(`col1`) sourceDF AS explod 
LATERAL VIEW explode(`col2`) explod AS explod2 
LATERAL VIEW explode(`col3`) explod2 AS explod3 
LATERAL VIEW explode(`col4`) explod3 AS explod4 
LATERAL VIEW explode(`col5`) explod4 AS explod5")

但我得到一个笛卡尔积,有很多重复项。 我也尝试过同样的方法,用 withcolumn 方法爆炸所有列,但仍然得到很多重复

.withColumn("col1", explode($"col1"))...

当然,我可以对最终的数据帧进行不同的处理,但这不是一个优雅的解决方案。 有没有办法在不得到所有这些重复项的情况下分解列?

谢谢!

【问题讨论】:

Explode (transpose?) multiple columns in Spark SQL table的可能重复 您好,这个问题是针对 Spark > 2.X 的,我们使用的是 Spark 1.6,因此针对该问题提供的大多数解决方案都不起作用。 【参考方案1】:

如果您使用的是 Spark 2.4.0 或更高版本,arrays_zip 可以让您更轻松地完成任务

val df = Seq(
  ("foo",
   Seq("Main", "Individual"),
   Seq(1777203, 1777203),
   Seq("GBP", "GBP"),
   Seq("CR", "CR"),
   Seq(143, 143)))
  .toDF("UserName", "col1", "col2", "col3", "col4", "col5")

df.select($"UserName",
          explode(arrays_zip($"col1", $"col2", $"col3", $"col4", $"col5")))
  .select($"UserName", $"col.*")
  .show()

输出:

+--------+----------+-------+----+----+----+
|UserName|      col1|   col2|col3|col4|col5|
+--------+----------+-------+----+----+----+
|     foo|      Main|1777203| GBP|  CR| 143|
|     foo|Individual|1777203| GBP|  CR| 143|
+--------+----------+-------+----+----+----+

【讨论】:

嗨@ollik1,我们使用的是Spark 1.6,所以“arrays_zip”方法不可用。

以上是关于横向视图/在 Spark 中用多列爆炸,得到重复的主要内容,如果未能解决你的问题,请参考以下文章

Hive 横向视图爆炸内部机制

Apache Spark 数据框列爆炸为多列

横向视图快速爆炸

在 Spark 丢失记录中爆炸 [重复]

Spark 1.6以空值爆炸[重复]

如何使用scala在Apache spark中用空字符串(“”)替换空值[重复]