Saltar al contenido

PySpark: cambie el nombre de más de una columna usando withColumnRenamed

Solución:

No es posible utilizar un solo withColumnRenamed llama.

  • Puedes usar DataFrame.toDF método*

    data.toDF('x3', 'x4')
    

    o

    new_names = ['x3', 'x4']
    data.toDF(*new_names)
    
  • También es posible cambiar el nombre con un simple select:

    from pyspark.sql.functions import col
    
    mapping = dict(zip(['x1', 'x2'], ['x3', 'x4']))
    data.select([col(c).alias(mapping.get(c, c)) for c in data.columns])
    

Del mismo modo, en Scala puede:

  • Cambiar el nombre de todas las columnas:

    val newNames = Seq("x3", "x4")
    
    data.toDF(newNames: _*)
    
  • Cambiar el nombre del mapeo con select:

    val  mapping = Map("x1" -> "x3", "x2" -> "x4")
    
    df.select(
      df.columns.map(c => df(c).alias(mapping.get(c).getOrElse(c))): _*
    )
    

    o foldLeft + withColumnRenamed

    mapping.foldLeft(data){
      case (data, (oldName, newName)) => data.withColumnRenamed(oldName, newName) 
    }
    

* No confundir con RDD.toDF que no es una función variada, y toma los nombres de las columnas como una lista,

Tampoco pude encontrar una solución fácil de pyspark, así que construí la mía propia, similar a la de pandas df.rename(columns={'old_name_1':'new_name_1', 'old_name_2':'new_name_2'}).

def rename_columns(df, columns):
    if isinstance(columns, dict):
        for old_name, new_name in columns.items():
            df = df.withColumnRenamed(old_name, new_name)
        return df
    else:
        raise ValueError("'columns' should be a dict, like {'old_name_1':'new_name_1', 'old_name_2':'new_name_2'}")

Entonces tu solución se verá como data = rename_columns(data, {'x1': 'x3', 'x2': 'x4'})

Me ahorra algunas líneas de código, espero que también te ayude.

¿Por qué desea realizarlo en una sola línea si imprime el plan de ejecución? En realidad, se hace en una sola línea.

data = spark.createDataFrame([(1,2), (3,4)], ['x1', 'x2'])
data = (data
   .withColumnRenamed('x1','x3')
   .withColumnRenamed('x2', 'x4'))
data.explain()

PRODUCCIÓN

== Physical Plan ==
*(1) Project [x1#1548L AS x3#1552L, x2#1549L AS x4#1555L]
+- Scan ExistingRDD[x1#1548L,x2#1549L]

si desea hacerlo con una tupla de lista, puede usar una función de mapa simple

data = spark.createDataFrame([(1,2), (3,4)], ['x1', 'x2'])
new_names = [("x1","x3"),("x2","x4")]
data = data.select(list(
       map(lambda old,new:F.col(old).alias(new),*zip(*new_names))
       ))

data.explain()

todavía tiene el mismo plan

PRODUCCIÓN

== Physical Plan ==
*(1) Project [x1#1650L AS x3#1654L, x2#1651L AS x4#1655L]
+- Scan ExistingRDD[x1#1650L,x2#1651L]
¡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 *