2016-12-04 135 views
11

我有DataFramefew columns。現在我想添加兩列到現有的DataFrame。使用withColumn在現有DataFrame中添加兩列

目前我在DataFrame中使用withColumn方法。

例如:

df.withColumn("newColumn1", udf(col("somecolumn"))) 
    .withColumn("newColumn2", udf(col("somecolumn"))) 

其實我可以返回使用數組[字符串]在單個UDF方法都新列值。但目前這是我如何做到這一點。

無論如何,我可以有效地做到這一點?使用explode在這裏是不錯的選擇?

即使我必須使用explode,我必須使用withColumn一次,然後返回列值Array[String],然後使用explode,創建兩列。

哪一個是有效的?或者有沒有其他的選擇?

回答

23

AFAIk您需要撥打withColumn兩次(每個新列一次)。但是,如果你的udf在計算上很昂貴,你可以避免調用它兩次,將「複雜」結果存儲在臨時列中,然後「解包」結果,例如使用柱的apply方法(其給出到陣列元件訪問):

val myUDf = udf((s:String) => Array(s.toUpperCase(),s.toLowerCase())) 

val df = sc.parallelize(Seq("Peter","John")).toDF("name") 

val newDf = df 
    .withColumn("udfResult",myUDf(col("name"))) 
    .withColumn("uppercaseColumn", col("udfResult")(0)) 
    .withColumn("lowercaseColumn", col("udfResult")(1)) 
    .drop("udfResult") 

newDf.show() 

給出

+-----+---------------+---------------+ 
| name|uppercaseColumn|lowercaseColumn| 
+-----+---------------+---------------+ 
|Peter|   PETER|   peter| 
| John|   JOHN|   john| 
+-----+---------------+---------------+ 

我爲此經常,但不使用陣列,但使用的情況下的類或元組作爲結果從UDF

編輯:

隨着UDF返回一個元組,拆包是這樣的:

val newDf = df 
    .withColumn("udfResult",myUDf(col("name"))) 
    .withColumn("lowercaseColumn", col("udfResult._1")) 
    .withColumn("uppercaseColumn", col("udfResult._2")) 
    .drop("udfResult") 
+0

一個非常有趣的方法。您是否衡量了您可以獲得的實際效益? –

+1

@AntonOkolnychyi當然,這取決於用例。我有一個UDF需要約500毫秒的時間來計算和生成40列輸出。所以在這種情況下,我絕對不想多次調用這個UDF。 ..所以我使用上述模式 –

+0

@RaphaelRoth:謝謝,你如何使用Tuple的上述情況?你如何從列中得到元組的值?基本上用Columns接受col(「somecolumn」)作爲值。 – Shankar

相關問題