Saltar al contenido

Cambiar el nombre de las columnas de un DataFrame en Spark Scala

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *