ถ้าโครงสร้างแบน:
val df = Seq((1L, "a", "foo", 3.0)).toDF
df.printSchema
สิ่งที่ง่ายที่สุดที่คุณสามารถทำได้คือใช้toDF
method:
val newNames = Seq("id", "x1", "x2", "x3")
val dfRenamed = df.toDF(newNames: _*)
dfRenamed.printSchema
หากคุณต้องการเปลี่ยนชื่อคอลัมน์แต่ละคอลัมน์คุณสามารถใช้ได้select
กับalias
:
df.select($"_1".alias("x1"))
ซึ่งสามารถสรุปเป็นหลายคอลัมน์ได้อย่างง่ายดาย:
val lookup = Map("_1" -> "foo", "_3" -> "bar")
df.select(df.columns.map(c => col(c).as(lookup.getOrElse(c, c))): _*)
หรือwithColumnRenamed
:
df.withColumnRenamed("_1", "x1")
ซึ่งใช้foldLeft
เพื่อเปลี่ยนชื่อหลายคอลัมน์:
lookup.foldLeft(df)((acc, ca) => acc.withColumnRenamed(ca._1, ca._2))
ด้วยโครงสร้างที่ซ้อนกัน ( structs
) ทางเลือกหนึ่งที่เป็นไปได้คือการเปลี่ยนชื่อโดยการเลือกโครงสร้างทั้งหมด:
val nested = spark.read.json(sc.parallelize(Seq(
"""{"foobar": {"foo": {"bar": {"first": 1.0, "second": 2.0}}}, "id": 1}"""
)))
nested.printSchema
@transient val foobarRenamed = struct(
struct(
struct(
$"foobar.foo.bar.first".as("x"), $"foobar.foo.bar.first".as("y")
).alias("point")
).alias("location")
).alias("record")
nested.select(foobarRenamed, $"id").printSchema
โปรดทราบว่าอาจส่งผลต่อnullability
ข้อมูลเมตา ความเป็นไปได้อีกประการหนึ่งคือการเปลี่ยนชื่อโดยการแคสต์:
nested.select($"foobar".cast(
"struct<location:struct<point:struct<x:double,y:double>>>"
).alias("record")).printSchema
หรือ:
import org.apache.spark.sql.types._
nested.select($"foobar".cast(
StructType(Seq(
StructField("location", StructType(Seq(
StructField("point", StructType(Seq(
StructField("x", DoubleType), StructField("y", DoubleType)))))))))
).alias("record")).printSchema