scala 使用withColumn向现有DataFrame添加两列

6tqwzwtp  于 2023-05-29  发布在  Scala
关注(0)|答案(2)|浏览(154)

我有一个带有几列的DataFrame。现在我想向现有的DataFrame中再添加两列。
目前,我正在使用DataFrame中的withColumn方法来实现这一点。

例如:

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

实际上,我可以使用Array[String]在单个UDF方法中返回两个newcoOlumn值。但目前我就是这样做的。
无论如何,我能有效地做到这一点吗?使用explode是这里的好选择吗?
即使我必须使用explode,我也必须使用withColumn一次,然后将列值返回为Array[String],然后使用explode,再创建两列。
哪一个是有效的?还是有别的选择

**更新:**参考@blert答案,withColumns是要走的路。

4uqofj5v

4uqofj5v1#

AFAIK需要调用withColumn两次(每个新列一次)。但是如果你的udf在计算上很昂贵,你可以避免两次调用它,把“复杂”的结果存储在一个临时列中,然后“解包”结果。使用column的apply方法(可以访问数组元素)。请注意,有时需要缓存中间结果(以防止在解包期间每行调用UDF两次),有时则不需要。这似乎取决于Spark如何优化计划:

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")
mv1qrgav

mv1qrgav2#

2023年5月:现在可以使用新的withColumns(注意最后的's ')方法向现有的Spark Dataframe 添加几列,而无需多次调用withColumn。你只需要一张MapMap[String, Column]。给定两个UDF的例子udf1udf2,你可以像这样使用这个新方法:

val dfNew=df.withColumns(Map("newCol1"->udf1(col("oldCol1")),"newCol2"->udf2(col("oldCol2"))))

关于这方面的更多信息现在可以在官方文档中找到。

相关问题