Este grupo de especialistas pasados muchos días de trabajo y de recopilar de información, encontramos la respuesta, deseamos que te sea de utilidad en tu trabajo.
Solución:
Si la estructura es plana:
val df = Seq((1L, "a", "foo", 3.0)).toDF
df.printSchema
// root
// |-- _1: long (nullable = false)
// |-- _2: string (nullable = true)
// |-- _3: string (nullable = true)
// |-- _4: double (nullable = false)
lo más simple que puedes hacer es usar toDF
método:
val newNames = Seq("id", "x1", "x2", "x3")
val dfRenamed = df.toDF(newNames: _*)
dfRenamed.printSchema
// root
// |-- id: long (nullable = false)
// |-- x1: string (nullable = true)
// |-- x2: string (nullable = true)
// |-- x3: double (nullable = false)
Si desea cambiar el nombre de columnas individuales, puede usar cualquiera select
con alias
:
df.select($"_1".alias("x1"))
que se puede generalizar fácilmente a varias columnas:
val lookup = Map("_1" -> "foo", "_3" -> "bar")
df.select(df.columns.map(c => col(c).as(lookup.getOrElse(c, c))): _*)
o withColumnRenamed
:
df.withColumnRenamed("_1", "x1")
que usar con foldLeft
para cambiar el nombre de varias columnas:
lookup.foldLeft(df)((acc, ca) => acc.withColumnRenamed(ca._1, ca._2))
Con estructuras anidadas (structs
) una opción posible es cambiar el nombre seleccionando una estructura completa:
val nested = spark.read.json(sc.parallelize(Seq(
""""foobar": "foo": "bar": "first": 1.0, "second": 2.0, "id": 1"""
)))
nested.printSchema
// root
// |-- foobar: struct (nullable = true)
// | |-- foo: struct (nullable = true)
// | | |-- bar: struct (nullable = true)
// | | | |-- first: double (nullable = true)
// | | | |-- second: double (nullable = true)
// |-- id: long (nullable = true)
@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
// root
// |-- record: struct (nullable = false)
// | |-- location: struct (nullable = false)
// | | |-- point: struct (nullable = false)
// | | | |-- x: double (nullable = true)
// | | | |-- y: double (nullable = true)
// |-- id: long (nullable = true)
Tenga en cuenta que puede afectar nullability
metadatos Otra posibilidad es renombrar por casting:
nested.select($"foobar".cast(
"struct>>"
).alias("record")).printSchema
// root
// |-- record: struct (nullable = true)
// | |-- location: struct (nullable = true)
// | | |-- point: struct (nullable = true)
// | | | |-- x: double (nullable = true)
// | | | |-- y: double (nullable = true)
o:
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
// root
// |-- record: struct (nullable = true)
// | |-- location: struct (nullable = true)
// | | |-- point: struct (nullable = true)
// | | | |-- x: double (nullable = true)
// | | | |-- y: double (nullable = true)
Para aquellos de ustedes interesados en la versión PySpark (en realidad, es lo mismo en Scala; vea el comentario a continuación):
merchants_df_renamed = merchants_df.toDF(
'merchant_id', 'category', 'subcategory', 'merchant')
merchants_df_renamed.printSchema()
Resultado:
raíz
|– id_comerciante: entero (anulable = true)
|– categoría: string (anulable = true)
|– subcategoría: string (anulable = true)
|– comerciante: string (anulable = true)
def aliasAllColumns(t: DataFrame, p: String = "", s: String = ""): DataFrame =
t.select( t.columns.map c => t.col(c).as( p + c + s) : _* )
En caso de que no sea obvio, esto agrega un prefix y un sufijo para cada uno de los nombres de columna actuales. Esto puede ser útil cuando tiene dos tablas con una o más columnas con el mismo nombre, y desea unirlas pero aún puede eliminar la ambigüedad de las columnas en la tabla resultante. Seguro que sería bueno si hubiera una forma similar de hacer esto en SQL “normal”.
Agradecemos que desees estimular nuestra función mostrando un comentario o dejando una puntuación te damos la bienvenida.