为什么 posexplode 失败并显示 "AnalysisException: The number of aliases supplied in the AS clause does not match the number of columns..."?
Why does posexplode fail with "AnalysisException: The number of aliases supplied in the AS clause does not match the number of columns..."?
这是我的数据框:
+------------------------------------------
|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来"Creates a new row for each element with position in the given array or map column."
posexplode 需要 2 个引用名称来表示其创建的索引和它从每一行中的数组中提取的实际值。
您可以做的是在注册您的 table 或查看(与您使用的 spark 版本不同)后使用 'Lateral View',例如:
select ind, val from table_name LATERAL VIEW posexplode(values) exploded_values as ind, val
我在工作中没有尝试过这个,但你绝对可以试试这个。
您可以将 posexplode
与 select
一起使用,如下所示
dataframe.select($"value", posexplode($"value")).show(false)
其中 returns 两个新列作为 pos
和 col
希望对您有所帮助!
posexplode
将创建两个新列,一个包含值,一个包含索引。您可以使用:
dataFrame.select(posexplode($"value") as Seq("pos", "val"))
这将为您提供一个包含索引和值的数据框。
但是,如果您只想要实际值,最好使用 explode
:
dataFrame.withColumn("val", explode($"value"))
如果您在 .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|
+---+---+---+
这是我的数据框:
+------------------------------------------
|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来"Creates a new row for each element with position in the given array or map column."
posexplode 需要 2 个引用名称来表示其创建的索引和它从每一行中的数组中提取的实际值。
您可以做的是在注册您的 table 或查看(与您使用的 spark 版本不同)后使用 'Lateral View',例如:
select ind, val from table_name LATERAL VIEW posexplode(values) exploded_values as ind, val
我在工作中没有尝试过这个,但你绝对可以试试这个。
您可以将 posexplode
与 select
一起使用,如下所示
dataframe.select($"value", posexplode($"value")).show(false)
其中 returns 两个新列作为 pos
和 col
希望对您有所帮助!
posexplode
将创建两个新列,一个包含值,一个包含索引。您可以使用:
dataFrame.select(posexplode($"value") as Seq("pos", "val"))
这将为您提供一个包含索引和值的数据框。
但是,如果您只想要实际值,最好使用 explode
:
dataFrame.withColumn("val", explode($"value"))
如果您在 .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|
+---+---+---+