Apache spark 如何在spark dataframe中动态选择结构列?

Apache spark 如何在spark dataframe中动态选择结构列?,apache-spark,dataframe,apache-spark-sql,databricks,Apache Spark,Dataframe,Apache Spark Sql,Databricks,我试图推断struct的模式,并构建一个列表,其中包含用col括起来的struct字段,替换为:在dataframe的select列列表中使用uu作为别名。struct fields属性是可选的,因此我想基于输入数据构造select语句 架构推断为: val listOfProperties = explodeFeatures.schema .filter(c => c.name == "listOfFeatures") .flatMap(_.dataType.as

我试图推断struct的模式,并构建一个列表,其中包含用col括起来的struct字段,替换为:在dataframe的select列列表中使用uu作为别名。struct fields属性是可选的,因此我想基于输入数据构造select语句

架构推断为:

  val listOfProperties = explodeFeatures.schema
     .filter(c => c.name == "listOfFeatures")
     .flatMap(_.dataType.asInstanceOf[StructType].fields).filter(y => y.name == "properties").flatMap(_.dataType.asInstanceOf[StructType].fields)
     .map(_.name).map(x => "col(\"listOfFeatures.properties."+x+"\").as(\"properties_"+x.replace(":","_")+"\")")
上述声明的结果:val财产清单

col("type").as("type")
col("listOfFeatures.properties.a").as("properties_A"),
col("listOfFeatures.properties.b:P1").as("properties_b_P1"),
col("listOfFeatures.properties.C:ID").as("properties_C_ID"),
col("listOfFeatures.properties.D:l").as("properties_D_1")
Select语句:

explodeFeatures.select(listOfProperties .head , listOfProperties .tail : _*)
但是上面的语句在运行时无法解析。相反,如果我使用下面的硬编码,它成功了

explodeFeatures.select(
col("type").as("type"),
col("listOfFeatures.properties.a").as("properties_A"),
col("listOfFeatures.properties.b:P1").as("properties_b_P1"),
col("listOfFeatures.properties.C:ID").as("properties_C_ID"),
col("listOfFeatures.properties.D:l").as("properties_D_1"))
基于以下原因构建了一个列表

需要访问struct变量, 需要重命名该结构变量,因为它在列名中包含

有谁能告诉我为什么硬编码语句有效,而不是属性列表。头,属性列表。尾

例外情况:

线程主org.apache.spark.sql.AnalysisException中的异常: 无法解析给定输入列[type, 列表特性]


正如注释中所建议的,您的变量是一个Seq[String],当传递给select时,它看起来像df.selectcolname,这使它查找名为colname而不是name的列。您需要按如下方式更改上一张地图:

val listOfProperties=explodeFeatures.schema .filterc=>c.name==ListOffatures .flatMap_u2;.dataType.asInstanceOf[StructType]。字段 .filtery=>y.name==属性 .flatMap_u2;.dataType.asInstanceOf[StructType]。字段 .map\u.name .mapx=>colslistOfFeatures.properties.${x}.assproperties_${x.replace:,}
旁注:使用字符串插值。它更干净

listOfProperties是列表[字符串]吗?如果是,则应该是List[Column]查看其中的表达式。是,因为col值的concat是其Seq[String]。我怎样才能转换到Seq[column]它抛出了一个错误谢谢,replace不起作用我可以做一些变通,但是explodeFeatures.selectlistOfProperties.head,listOfProperties.tail:*显示了错误。如何选择所有列?使用selectlistOfProperties:*很好,达到了预期效果。