我有一个带有几列的DataFrame
。现在,我想在现有数据框架中添加两个列。
目前,我正在使用DataFrame中的withColumn
方法进行此操作。
例如:
df.withColumn("newColumn1", udf(col("somecolumn")))
.withColumn("newColumn2", udf(col("somecolumn")))
实际上,我可以使用Array [String]在单个UDF方法中返回两个NewCumumn值。但目前这就是我的方式。
无论如何,我可以有效地做到吗?使用explode
是这里的好选择吗?
即使我必须使用explode
,我也必须使用withColumn
,然后将列值返回为Array[String]
,然后使用explode
,创建两个列。
哪一个有效?还是有其他选择?
**更新:**请参阅@blert答案,withColumns
是要走的方法。
afaik您需要两次调用withColumn
(每列一次一次)。但是,如果您的UDF在计算上很昂贵,则可以在临时列中避免将其调用两次,然后"解开"结果,例如。使用列的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")
2023年5月:现在使用新的withColumns
(请注意最终's')方法,将几列添加到现有的Spark Dataframe中而无需致电几次withColumn
。您只需要一个地图Map[String, Column]
。给定两个udf的udf,用于此示例udf1
和udf2
您可以使用以下新方法:
val dfNew=df.withColumns(Map("newCol1"->udf1(col("oldCol1")),"newCol2"->udf2(col("oldCol2"))))
现在可以在官方文档中找到更多信息。