为什么posexplode失败并出现“AnalysisException:AS子句中提供的别名数与列数不符......”?

时间:2018-01-03 08:39:53

标签: apache-spark apache-spark-sql spark-dataframe

这是我的数据框:

+------------------------------------------
|value   
+------------------------------------------
|[0.0, 1.0, 0.0, 7.0000000000000036, 0.0]
|[2.0000000000000036, 0.0, 2.9999999999999996, 4.0000000000000036, 5.000000000000002]
|[4.000000000000006, 0.0, 0.0, 6.000000000000006, 7.000000000000004]  
+------------------------------------------

当我使用时:

dataFrame.withColumn("item_id", posexplode(dataFrame.col("value")))

我收到了这个错误:

org.apache.spark.sql.AnalysisException: The number of aliases supplied in the AS clause does not match the number of columns output by the UDTF expected 2 aliases but got item_id ;

那么,如何使用posexplode“为给定数组或地图列中具有位置的每个元素创建一个新行。”

4 个答案:

答案 0 :(得分:6)

如果您要在explode中使用.withColumn(),一切都会很清楚。

相比之下,在低优先级的Spark-20174被接受和实现之前,posexplodewithColumn的结合使用并非一帆风顺。您可能要使用基于selectExpr的解决方法,如下所示。

val df = Seq(
  ("a", Seq(1,2,3)),
  ("b", Seq(11,22))).toDF("n", "s")
df show

+---+---------+
|  n|        s|
+---+---------+
|  a|[1, 2, 3]|
|  b| [11, 22]|
+---+---------+
df selectExpr("*", "posexplode(s) as (p,c)") drop("s") show

+---+---+---+
|  n|  p|  c|
+---+---+---+
|  a|  0|  1|
|  a|  1|  2|
|  a|  2|  3|
|  b|  0| 11|
|  b|  1| 22|
+---+---+---+

答案 1 :(得分:4)

您可以posexplode使用select,如下所示

dataframe.select($"value", posexplode($"value")).show(false)

返回两个新列poscol

希望这有帮助!

答案 2 :(得分:1)

posexplode需要2个引用名称来表示其创建的索引以及从每行中的数组中提取的实际值。

您可以做的是在注册表格或视图后使用“横向视图”(与您使用的火花版本不同),例如:

select ind, val from table_name LATERAL VIEW posexplode(values) exploded_values as ind, val

我没有尝试过,因为我在工作场所,但你绝对可以试试这个。

答案 3 :(得分:1)

posexplode将创建两个新列,一个包含值,另一个包含索引。您可以使用:

dataFrame.select(posexplode($"value") as Seq("pos", "val"))

这将为您提供包含索引和值的数据框。

但是,如果您只想要实际值,最好使用explode

dataFrame.withColumn("val", explode($"value"))