这是我的数据帧:
+------------------------------------------
|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来"为每个元素创建一个新行,并在给定的数组或映射列中具有位置。
如果你在.withColumn()
中使用explode
,事情就很清楚了。
相比之下,在低优先级的Spark-20174被接受和实施之前,使用posexplode
和withColumn
并不简单。您可能希望使用基于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|
+---+---+---+
您可以将posexplode
与select
一起使用,如下所示
dataframe.select($"value", posexplode($"value")).show(false)
这将返回两个新列作为pos
和col
希望这有帮助!
posexplode
将创建两个新列,一个包含值,一个包含索引。您可以使用:
dataFrame.select(posexplode($"value") as Seq("pos", "val"))
这将为您提供一个包含索引和值的数据帧。
但是,如果您只想要实际值,最好使用 explode
:
dataFrame.withColumn("val", explode($"value"))
posexplosion 需要 2 个引用名称来表示其创建的索引和它从每行数组中提取的实际值。
您可以做的是在注册表或视图(与您使用的 Spark 版本不同(后使用"横向视图",例如:
select ind, val from table_name LATERAL VIEW posexplode(values) exploded_values as ind, val
我没有尝试过这个,因为我在工作场所,但你绝对可以尝试一下。