Spark withColumn修改列生效,新增lastRanOn列失败如何解决?
问题:Spark DataFrame执行withColumn新增列未生效?
我来帮你搞定这个问题!首先得明确Spark里的一个核心特性:DataFrame是不可变的(immutable)——所有像withColumn这样的转换操作,都不会修改原有的DataFrame,而是返回一个全新的DataFrame对象。
看你写的这段代码:
myDf.show(5) myDf.withColumn("rank", myDf("rank") * 10) myDf.withColumn("lastRanOn", current_date()) println("And now:") myDf.show(5)
你连续调用了两次withColumn,但都没有把返回的新DataFrame赋值给任何变量,所以原有的myDf完全没变化。你觉得第一个withColumn生效了,大概率是测试时的小误会(比如之前的代码里有赋值操作),实际上这两个操作都没对原DataFrame产生影响。
解决方法
方法1:分步赋值
把每次转换后的新DataFrame保存到变量中,逐步更新:myDf.show(5) // 第一次转换:更新rank列,结果存到新变量 val updatedDf = myDf.withColumn("rank", myDf("rank") * 10) // 第二次转换:基于更新后的DataFrame新增lastRanOn列 val finalDf = updatedDf.withColumn("lastRanOn", current_date()) println("And now:") finalDf.show(5)如果不想用多个新变量,也可以直接覆盖原变量(注意原变量如果是
val要改成var,不过更推荐用新变量来保持不可变性):var myDf = ... // 初始化你的DataFrame myDf.show(5) myDf = myDf.withColumn("rank", myDf("rank") * 10) myDf = myDf.withColumn("lastRanOn", current_date()) println("And now:") myDf.show(5)方法2:链式调用(更符合Spark的编程风格)
把多个转换操作连在一起,代码更简洁紧凑:myDf.show(5) val finalDf = myDf .withColumn("rank", col("rank") * 10) // 用col()函数比直接myDf("rank")更灵活 .withColumn("lastRanOn", current_date()) println("And now:") finalDf.show(5)注意:要确保已经导入了Spark的函数包
org.apache.spark.sql.functions._,不然current_date()和col()这些内置函数会报错找不到。
这样修改后,你就能看到rank列的值被乘以10,同时成功新增了lastRanOn列显示当前日期啦!
内容的提问来源于stack exchange,提问作者hotmeatballsoup
相关产品推荐
相关产品推荐

