使用withColumn将两列添加到现有DataFrame

时间:2016-12-04 14:30:46

标签: scala dataframe apache-spark-sql

我有withColumn,其中有几列。现在我想再向现有的DataFrame添加两列。

目前我在DataFrame中使用df.withColumn("newColumn1", udf(col("somecolumn"))) .withColumn("newColumn2", udf(col("somecolumn"))) 方法执行此操作。

例如:

explode

实际上我可以使用Array [String]在单个UDF方法中返回两个newcoOlumn值。但目前我正是这样做的。

无论如何,我能有效地做到这一点吗?使用explode是不错的选择?

即使我必须使用withColumn,我也必须使用Array[String]一次,然后将列值返回为explode,然后使用<?php require_once("PHPMailer-master/class.phpmailer.php"); $mail = new PHPMailer(); $mail->addAddress("mehregan.programmer@gmail.com"); // recipient Email $mail->setFrom("info@mehregan-software.ir"); // Sender Email $mail->Subject="title"; $mail->Body="hello world !"; $mail->isSMTP(); $mail->Host="mail.mehregan-software.ir"; // SMTP Host $mail->Username="info@mehregan-software.ir"; //I created this mail in my host $mail->Password="*****"; // password for email $mail->SMTPSecure="ssl"; $mail->Port=465; $mail->SMTPAuth = true; if(!$mail->Send()) { echo 'Message was not sent.'; echo 'Mailer error: ' . $mail->ErrorInfo; exit; } else { echo 'Message has been sent.'; } ?> ,再创建两列

哪一个有效?或者有其他选择吗?

1 个答案:

答案 0 :(得分:41)

AFAIk您需要拨打withColumn两次(每个新列一次)。但是如果你的udf在计算上很昂贵,那么你可以避免在存储&#34;复杂&#34;导致临时列,然后&#34;解包&#34;结果,例如使用列的apply方法(可以访问数组元素)。请注意,有时需要缓存中间结果(以防止在解包期间每行调用两次UDF),有时不需要它。这似乎取决于优化计划的火花:

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"))).cache 
  .withColumn("uppercaseColumn", col("udfResult")(0))
  .withColumn("lowercaseColumn", col("udfResult")(1))
  .drop("udfResult")

newDf.show()

给出

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

使用UDF返回元组,解压缩将如下所示:

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