如何更改pyspark中的数据框列名?
我来自pandas的背景,习惯于从CSV文件中读取数据到数据框中,然后使用简单的命令简单地将列名更改为有用的东西:
df.columns = new_column_name_list
但是,在使用sqlContext创build的pyspark数据框中不起作用。 我可以想出的唯一解决scheme就是:
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)
这基本上定义了两次variables,首先推断模式,然后重命名列名,然后再次使用更新的模式加载数据框。
有没有比pandas更好更高效的方法来做到这一点?
我的火花版本是1.5.0
有很多方法可以做到这一点:
-
选项1.使用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)
-
选项2.使用withColumnRenamed ,请注意,此方法允许您“覆盖”相同的列。
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()
-
选项3.使用别名 ,在Scala中你也可以使用as 。
from pyspark.sql.functions import * data = data.select(col("Name").alias("name"), col("askdaosdka").alias("age")) data.show() # Output #+-------+---+ #| name|age| #+-------+---+ #|Alberto| 2| #| Dakota| 2| #+-------+---+
-
选项4.使用sqlContext.sql ,它允许您在注册为表的
DataFrames
上使用SQL查询。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")
使用这种方法的优点:对于很长的列列表,您只想更改less数列名称。 这在这些情况下可以非常方便。 连接具有重复列名称的表非常有用。
如果你想重命名一个列,并保持原状:
from pyspark.sql.functions import col new_df = old_df.select(*[col(s).alias(new_name) if s == column_to_change else s for s in old_df.columns])
如果要更改所有列名称,请尝试df.toDF(*cols)
对于单列重命名,您仍然可以使用toDF()。 例如,
df1.selectExpr("SALARY*2").toDF("REVISED_SALARY").show()