Sql scala spark使用spark shell中的udf函数在dataframe列中进行数组操作
scala/spark使用spark shell中的udf函数在dataframe列中进行数组操作Sql scala spark使用spark shell中的udf函数在dataframe列中进行数组操作,sql,scala,apache-spark,dataframe,user-defined-functions,Sql,Scala,Apache Spark,Dataframe,User Defined Functions,scala/spark使用spark shell中的udf函数在dataframe列中进行数组操作 df.printSchema root |-- x: timestamp (nullable = true) |-- date_arr: array (nullable = true) | |-- element: timestamp (containsNull = true) 样本数据: |x | date_arr
df.printSchema
root
|-- x: timestamp (nullable = true)
|-- date_arr: array (nullable = true)
| |-- element: timestamp (containsNull = true)
样本数据:
|x | date_arr |
|---------------------- |---------------------------------------------------------------------- |
| 2009-10-22 19:00:00.0 | [2009-08-22 19:00:00.0, 2009-09-19 19:00:00.0, 2009-10-24 19:00:00.0] |
| 2010-10-02 19:00:00.0 | [2010-09-25 19:00:00.0, 2010-10-30 19:00:00.0] |
在udf.jar中,我有一个函数可以根据x在date_arr中获取天花板日期:
class CeilToDate extends UDF {
def evaluate(arr: Seq[Timestamp], x: Timestamp): Timestamp = {
arr.filter(_.before(x)).last
}
}
将jar添加到sparkshell:sparkshell--jars udf.jar
在spark shell中,我将HiveContext设置为val hc=new HiveContext(spc)
,并创建函数:hc.sql(“将临时函数ceil\u创建为'com.abc.udf.CeilToDate'”
当我进行查询时:hc.sql(“选择ceil\u to\u date(date\u arr,x)作为来自df的ceildate”)。show
,希望有一个类似于:
|ceildate |
|----------------------|
|2009-09-19 19:00:00.0 |
|2010-09-25 19:00:00.0 |
但是,它会抛出以下错误:
org.apache.spark.sql.AnalysisException:没有配置单元udf类com.abc.udf.CeilToDate的处理程序,因为:没有将类com.abc.udf.CeilToDate与(数组,时间戳)匹配的方法。可能的选择:FUNC(struct,timestamp)为什么要经历创建udf jar的所有复杂过程,并将jar包含在spark shell中。您只需在spark shell中创建一个,并在数据帧中使用它即可 假设您有
dataframe
as
scala> df.show(false)
+---------------------+---------------------------------------------------------------------+
|x |date_arr |
+---------------------+---------------------------------------------------------------------+
|2009-10-22 19:00:00.0|[2009-08-22 19:00:00.0, 2009-09-19 19:00:00.0, 2009-10-24 19:00:00.0]|
|2010-10-02 19:00:00.0|[2010-09-25 19:00:00.0, 2010-10-30 19:00:00.0] |
+---------------------+---------------------------------------------------------------------+
您可以在spark shell中创建一个udf
函数,但在此之前,您需要三个imports
scala> import org.apache.spark.sql.functions._
import org.apache.spark.sql.functions._
scala> import java.sql.Timestamp
import java.sql.Timestamp
scala> import scala.collection._
import scala.collection._
然后您可以创建一个udf函数
scala> def ceil_to_date = udf((arr: mutable.WrappedArray[Timestamp], x: Timestamp) => arr.filter(_.before(x)).last)
ceil_to_date: org.apache.spark.sql.expressions.UserDefinedFunction
可以通过不同的方法实现所需的输出dataframe
,但只需使用select
as即可
scala> df.select(ceil_to_date(col("date_arr"), col("x")).as("ceildate")).show(false)
+---------------------+
|ceildate |
+---------------------+
|2009-09-19 19:00:00.0|
|2010-09-25 19:00:00.0|
+---------------------+
我希望答案有帮助我试图直接在spark shell中定义udf。此步骤之前没有错误:df.select(cell\u to\u date($“date\u arr,$“x”))。这个步骤给了我这个错误:错误2017-09-10 13:59:00844 org.apache.spark.scheduler.TaskSetManager:stage 12.0中的任务0失败了4次;中止作业org.apache.spark.SparkException:作业因阶段失败而中止:阶段12.0中的任务0失败4次,最近的失败:阶段12.0中的任务0.3丢失(TID 439):java.lang.ClassNotFoundException。完整的错误消息请参见此处:我已更新了最后一步。:)您需要导入sqlContext.implicits.\u我理解$和col()。问题不是因为这个。我尝试了,但仍然收到相同的错误消息。消息是未识别udf函数。您使用的spark版本是什么?在调用udf函数之前,您能否确保表的模式与您发布的完全相同?在DSE 5.0.5中,Apache Spark 1.6.2.3。我确信模式是df.printSchema