¿Cómo cambiar los nombres de las columnas del marco de datos en PySpark?
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
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
xrange
conrange
.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
DataFrames
tablas 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| #+-------+---+
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.
Si desea cambiar todos los nombres de las columnas, intentedf.toDF(*cols)