在Spark中展开结构列时出现错误

15

我有一个数据框,其模式看起来像这样:

event: struct (nullable = true)
|    | event_category: string (nullable = true)
|    | event_name: string (nullable = true)
|    | properties: struct (nullable = true)
|    |    | ErrorCode: string (nullable = true)
|    |    | ErrorDescription: string (nullable = true)

我正在尝试使用以下代码来展开properties列的struct

```python explode("properties") ```

df_json.withColumn("event_properties", explode($"event.properties"))

但它抛出了以下异常:

cannot resolve 'explode(`event`.`properties`)' due to data type mismatch: 
input to function explode should be array or map type, 
not StructType(StructField(IDFA,StringType,true),
如何展开列properties

1
由于该问题已被标记为与此问题重复,您的关闭投票现在会导致循环重复导航(如果现在尝试,则无效)。 - Nick stands with Ukraine
3个回答

12

您可以在 数组映射 中使用 explode,因此需要将 属性 结构体 转换为 数组,然后按如下方式应用 explode 函数。

import org.apache.spark.sql.functions._
df_json.withColumn("event_properties", explode(array($"event.properties.*"))).show(false)

您应该拥有自己想要的需求。


3
如何将 Map 转换为字符串形式。我也需要键名。 - shiva.n404
你使用的是哪个数组函数?这是Pyspark的ArrayType数据类型函数吗?还是通常作为F.<func>导入的SQL函数? - Artem Yevtushenko
数组是我导入的Spark SQL函数。 - Ramesh Maharjan

8

正如错误信息所述,您只能展开数组或映射类型,而不能展开结构类型列。

您可以直接执行

df_json.withColumn("event_properties", $"event.properties")

这将生成一个新列event_properties,它也是结构类型。
如果您想将结构的每个元素转换为一个新列,则不能使用withColumn,您需要使用通配符*进行select操作:
df_json.select($"event.properties.*")

0
您可以使用以下方法来展开结构。由于错误信息所述,Explode无法用于结构。
val explodeDF = parquetDF.explode($"event") { 
case Row(properties: Seq[Row]) => properties.map{ property =>
  val errorCode = property(0).asInstanceOf[String]
  val errorDescription = property(1).asInstanceOf[String]
  Event(errorCode, errorDescription, email, salary)
 }
}.cache()
display(explodeDF)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接