簡體   English   中英

spark中如何根據源列動態添加列 scala dataframe

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM