![](/img/trans.png)
[英]How to change datatype of columns in a dataframe based on a case class in scala/spark
[英]How to dynamically add columns based on source columns in spark scala dataframe
我需要根據新列更新的DF。 但它沒有用新列更新,它仍然給我舊列及其名稱
val schema = "sku_cd#sku_code,ean_nbr#ean,vnr_cd#nan_key,dsupp_pcmdty_desc#pack_descr"
val schemaArr = schema.split(",")
var df = spark.sql("""select sku_code, ean , nan_key, pack_descr from db.products""")
val updatedDF = populateAttributes(df,schemaArr)
def populateAttributes(df:DataFrame,schemaArr:Array[String]) : DataFrame = {
for(i <- schemaArr)
{
val targetCol = i.split("#")(0)
val sourceCol = i.split("#")(1)
df.withColumn(targetCol, col(sourceCol))
}
df
}
我低於 output 這是不正確的
scala> updatedDF.printSchema
root
|-- sku_code: string (nullable = true)
|-- ean: string (nullable = true)
|-- nan_key: string (nullable = true)
|-- pack_descr: string (nullable = true)
預期 output
|-- sku_cd: string (nullable = true)
|-- ean_nbr: string (nullable = true)
|-- vnr_cd: string (nullable = true)
|-- dsupp_pcmdty_desc: string (nullable = true)
您沒有在 for 循環中更新 dataframe。 該行:
df.withColumn(targetCol, col(sourceCol))
將創建一個新的 dataframe 和df
將保持不變。
您可以使用var
在每次迭代中重新分配原始 dataframe。 還可以使用withColumnRenamed
重命名列:
df = df.withColumnRenamed(sourceCol, targetCol)
或者更好的是,使用foldLeft
:
def populateAttributes(df:DataFrame,schemaArr:Array[String]) : DataFrame = {
schemaArr.foldLeft(df)((acc, m) => {
val mapping = m.split("#")
acc.withColumnRenamed(mapping(1), mapping(0))
})
}
使用 select 表達式的另一種方法:
val selectExpr = schemaArr.map(m => {
val mapping = m.split("#")
col(mapping(1)).as(mapping(0))
})
val updatedDF = df.select(selectExpr:_*)
做黑主教所做的另一種方式
val schema = "sku_cd#sku_code,ean_nbr#ean,vnr_cd#nan_key,dsupp_pcmdty_desc#pack_descr"
val schemaArr = schema.split(",").toSeq
val outputDF=schemaArr.foldLeft(inputDF)((df,x)=>df.withColumnRenamed(x,x.split('#')(0)))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.