使用具有常量值的 var 在 Spark DataFrame 中创建一个新列

Posted

技术标签:

【中文标题】使用具有常量值的 var 在 Spark DataFrame 中创建一个新列【英文标题】:Create a new column in a Spark DataFrame using a var with constant value 【发布时间】:2018-06-07 05:21:46 【问题描述】:

我正在尝试使用定义为var 的常量在 Spark DataFrame 中定义一个新列。我正在使用 Zeppelin - 在初始单元格中,它以

开头
%spark
import org.apache.spark.sql.functions._
var year : Int = 2016
spark.read.parquet("<path/to/file>")

该文件包含名为birth_year 的列;我想创建一个名为age 的新列,定义为$year - birth_year,其中birth_year 是一个字符串列。当UDF 的输入参数是参数时,我不太清楚如何执行此操作。我进行了几个小时的搜索并创建了一个UDF,但我收到一条错误消息,其主要部分是

<console>:71: error: type mismatch;
 found   : Int
 required: org.apache.spark.sql.Column
       spark.read.parquet("path/to/file").withColumn("birth_year", $"birth_year" cast "Int").withColumn("age", createAge(year, col("birth_year"))).createOrReplaceTempView("tmp")

和“年份”正下方的插入符号。

我怀疑$year 没有映射到与birth_year 长度相同的变量;我已经看到似乎适用于字符串的lit() 函数 - 它是否也适用于整数值,或者是否有其他函数用于此目的?

我尝试了以下方法:

%spark
import org.apache.spark.sql.functions._
var year : Int = 2016
def createAge = udf((yr : Int, dob : Int) => yr - dob)
spark.read.parquet("<path/to/file>").withColumn("birth_year", $"birth_year" cast "Int").withColumn("age", createAge($"year", col("birth_year"))).createOrReplaceTempView("tmp")

欢迎提出任何建议 - 提前感谢您的帮助。

【问题讨论】:

How can I pass extra parameters to UDFs in SparkSql?的可能重复 【参考方案1】:

您不能将year 直接用作UDF 的输入,因为它需要对列进行操作。要创建具有常量值的列,请使用lit()。您可以拨打UDF如下:

df.withColumn("age", createAge(lit(year), $"birth_year".cast("int")))

但是,在可能的情况下,始终首选使用 Spark 中的内置函数。在这种情况下,您不需要UDF。只需这样做:

df.withColumn("age", lit(year) - $"birth_year".cast("int"))

这应该快得多。

【讨论】:

以上是关于使用具有常量值的 var 在 Spark DataFrame 中创建一个新列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spark DataFrame 中添加常量列?

使用 Java 在 Spark Data Frame 中添加空值列

使用 databricks 在 Spark(scala) 中生成具有属性和值的 XML

如何在 Spark 数据框中添加具有序列值的列?

如何在 Spark/Scala 中查找具有许多空值的列

读取 CSV 后具有奇怪值的 Spark 数据帧