¿Cómo cambiar los nombres de las columnas del marco de datos en PySpark?

Resuelto Shubhanshu Mishra asked hace 8 años • 26 respuestas

Vengo de pandas y estoy acostumbrado a leer datos de archivos CSV en un marco de datos y luego simplemente cambiar los nombres de las columnas a algo útil usando el comando simple:

df.columns = new_column_name_list

Sin embargo, lo mismo no funciona en los marcos de datos de PySpark creados con sqlContext. La única solución que pude encontrar para hacer esto fácilmente es la siguiente:

df = sqlContext.read.format("com.databricks.spark.csv").options(header='false', inferschema='true', delimiter='\t').load("data.txt")
oldSchema = df.schema
for i,k in enumerate(oldSchema.fields):
  k.name = new_column_name_list[i]
df = sqlContext.read.format("com.databricks.spark.csv").options(header='false', delimiter='\t').load("data.txt", schema=oldSchema)

Básicamente, se trata de definir la variable dos veces e inferir el esquema primero, luego cambiar el nombre de las columnas y luego cargar el marco de datos nuevamente con el esquema actualizado.

¿Existe una manera mejor y más eficiente de hacer esto como lo hacemos con los pandas?

Mi versión de Spark es 1.5.0

Shubhanshu Mishra avatar Dec 04 '15 05:12 Shubhanshu Mishra
Aceptado

Hay muchas maneras de hacerlo:

  • Opción 1. Usando selectExpr .

     data = sqlContext.createDataFrame([("Alberto", 2), ("Dakota", 2)], 
                                       ["Name", "askdaosdka"])
     data.show()
     data.printSchema()
    
     # Output
     #+-------+----------+
     #|   Name|askdaosdka|
     #+-------+----------+
     #|Alberto|         2|
     #| Dakota|         2|
     #+-------+----------+
    
     #root
     # |-- Name: string (nullable = true)
     # |-- askdaosdka: long (nullable = true)
    
     df = data.selectExpr("Name as name", "askdaosdka as age")
     df.show()
     df.printSchema()
    
     # Output
     #+-------+---+
     #|   name|age|
     #+-------+---+
     #|Alberto|  2|
     #| Dakota|  2|
     #+-------+---+
    
     #root
     # |-- name: string (nullable = true)
     # |-- age: long (nullable = true)
    
  • Opción 2. Usando withColumnRenamed , observe que este método le permite "sobrescribir" la misma columna. Para Python3, reemplácelo xrangecon range.

     from functools import reduce
    
     oldColumns = data.schema.names
     newColumns = ["name", "age"]
    
     df = reduce(lambda data, idx: data.withColumnRenamed(oldColumns[idx], newColumns[idx]), xrange(len(oldColumns)), data)
     df.printSchema()
     df.show()
    
  • Opción 3. Usando alias , en Scala también puedes usar as .

     from pyspark.sql.functions import col
    
     data = data.select(col("Name").alias("name"), col("askdaosdka").alias("age"))
     data.show()
    
     # Output
     #+-------+---+
     #|   name|age|
     #+-------+---+
     #|Alberto|  2|
     #| Dakota|  2|
     #+-------+---+
    
  • Opción 4. Usar sqlContext.sql , que le permite usar consultas SQL en DataFramestablas registradas.

     sqlContext.registerDataFrameAsTable(data, "myTable")
     df2 = sqlContext.sql("SELECT Name AS name, askdaosdka as age from myTable")
    
     df2.show()
    
     # Output
     #+-------+---+
     #|   name|age|
     #+-------+---+
     #|Alberto|  2|
     #| Dakota|  2|
     #+-------+---+
    
Alberto Bonsanto avatar Dec 03 '2015 22:12 Alberto Bonsanto
df = df.withColumnRenamed("colName", "newColName")\
       .withColumnRenamed("colName2", "newColName2")

Ventaja de usar de esta manera: con una lista larga de columnas, le gustaría cambiar solo algunos nombres de columnas. Esto puede resultar muy conveniente en estos escenarios. Muy útil al unir tablas con nombres de columnas duplicados.

Pankaj Kumar avatar Mar 30 '2016 07:03 Pankaj Kumar

Si desea cambiar todos los nombres de las columnas, intentedf.toDF(*cols)

user8117731 avatar Jun 06 '2017 05:06 user8117731