DataFrame drop column无法正常工作

时间:2018-02-28 16:13:50

标签: scala apache-spark apache-spark-sql

我有一个DataFrame df,其中包含以下架构:

root
 |-- car: string (nullable = true)
 |-- person: struct (nullable = true)
 |    |-- age: long (nullable = true)
 |    |-- name: string (nullable = true)

然后我做:new_df = df.drop("person.name")。我还尝试了df.drop(col("person.name")) new_df的模式:

root
 |-- car: string (nullable = true)
 |-- person: struct (nullable = true)
 |    |-- age: long (nullable = true)
 |    |-- name: string (nullable = true)

new_df的架构没有改变。知道为什么吗? 假设我想要(person.age,car)的最终结果,该怎么做?

1 个答案:

答案 0 :(得分:2)

您必须将person struct列分隔为单独的列,然后使用drop

new_df.select("car", "person.*").drop("name")

如果您想要person.age,那么您可以构建将其重新标记为struct

import org.apache.spark.sql.functions._
new_df
  .select("car", "person.*")
  .drop("name")
  .withColumn("person", struct("age"))
  .drop("age")

root
 |-- car: string (nullable = true)
 |-- person: struct (nullable = false)
 |    |-- age: long (nullable = true)

正如@RaphaelRoth在下面的评论中指出的那样,你可以使用

new_df.select($"car",struct($"person.age").as("person"))

甚至更短

new_df.withColumn("person", struct("person.age"))

udf方式

您甚至可以udf方式进行此操作(不建议使用)(仅供参考)

import org.apache.spark.sql.functions._
def removeStruct = udf((p: personOld)=> person(p.age))

new_df.withColumn("person", removeStruct(col("person")))

为此你需要两个case classes

case class personOld(age: Long, name: String)
case class person(age: Long)