Как изменить имена столбцов dataframe в pyspark?
Я пришел из фона панды и привык читать данные из CSV-файлов в фрейм данных, а затем просто изменять имена столбцов на что-то полезное с помощью простой команды:
df.columns = new_column_name_list
однако то же самое не работает в фреймах данных pyspark, созданных с помощью sqlContext. Единственное решение, которое я мог бы выяснить, чтобы сделать это легко, это следующее:
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)
это в основном определение переменной дважды и вывод схемы сначала переименование столбца имена, а затем снова загрузить фрейм данных с обновленной схемой.
моя версия spark-1.5.0
9 ответов:
есть много способов сделать это:
- 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 вы также можете использовать как.
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, что позволяет использовать SQL-запросы на
DataFrames
зарегистрирован в качестве таблицы.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")
преимущество использования этого способа: с длинным списком столбцов вы хотели бы изменить только несколько имен столбцов. Это может быть очень удобно в этих сценариях. Очень полезно при соединении таблиц с повторяющимися именами столбцов.
Если вы хотите переименовать один столбец и сохранить оставшееся, как это:
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])
Если вы хотите применить простое преобразование ко всем именам столбцов, этот код делает трюк: (я заменяю все пробелы подчеркиванием)
new_column_name_list= list(map(lambda x: x.replace(" ", "_"), df.columns)) df = df.toDF(*new_column_name_list)
спасибо @user8117731 за
toDf
трюк.
другой способ переименовать только один столбец (используя
import pyspark.sql.functions as F
):df = df.select( '*', F.col('count').alias('new_count') ).drop('count')