scala – 如何对数组列的元素进行切片和求和?
我想使用SparkSQL对数组列求和(或执行其他聚合函数).
我有一张桌子 +-------+-------+---------------------------------+ |dept_id|dept_nm| emp_details| +-------+-------+---------------------------------+ | 10|Finance| [100,200,300,400,500]| | 20| IT| [10,20,50,100]| +-------+-------+---------------------------------+ 我想总结这个emp_details列的值. 预期查询: sqlContext.sql("select sum(emp_details) from mytable").show 预期结果 1500 180 此外,我应该能够总结范围元素: sqlContext.sql("select sum(slice(emp_details,3)) from mytable").show 结果 600 80 当对数组类型进行求和时,它表示sum预期参数为数字类型而不是数组类型. 我认为我们需要为此创建UDF.但怎么样? 我是否会面临使用UDF的任何性能命中? 解决方法
Spark 2.4.0
从Spark 2.4开始,Spark SQL支持用于处理复杂数据结构(包括数组)的高阶函数. “现代”解决方案如下: scala> input.show(false) +-------+-------+-------------------------+ |dept_id|dept_nm|emp_details | +-------+-------+-------------------------+ |10 |Finance|[100,500]| |20 |IT |[10,100] | +-------+-------+-------------------------+ input.createOrReplaceTempView("mytable") val sqlText = "select dept_id,dept_nm,aggregate(emp_details,(value,acc) -> value + acc) as sum from mytable" scala> sql(sqlText).show +-------+-------+----+ |dept_id|dept_nm| sum| +-------+-------+----+ | 10|Finance|1500| | 20| IT| 180| +-------+-------+----+ 您可以在以下文章和视频中找到关于高阶函数的好读物: > Introducing New Built-in and Higher-Order Functions for Complex Data Types in Apache Spark 2.4 Spark 2.3.2及更早版本 免责声明我不推荐这种方法(即使它得到了最多的赞成),因为Spark SQL执行数据集.map的反序列化.该查询强制Spark反序列化数据并将其加载到JVM(从JVM外部的Spark管理的内存区域).这将不可避免地导致更频繁的GC,从而使性能变差. 一种解决方案是使用数据集解决方案,其中Spark SQL和Scala的组合可以显示其功能. scala> val inventory = Seq( | (10,"Finance",Seq(100,500)),| (20,"IT",Seq(10,100))).toDF("dept_id","dept_nm","emp_details") inventory: org.apache.spark.sql.DataFrame = [dept_id: int,dept_nm: string ... 1 more field] // I'm too lazy today for a case class scala> inventory.as[(Long,String,Seq[Int])]. map { case (deptId,deptName,details) => (deptId,details.sum) }. toDF("dept_id","sum"). show +-------+-------+----+ |dept_id|dept_nm| sum| +-------+-------+----+ | 10|Finance|1500| | 20| IT| 180| +-------+-------+----+ 我将切片部分作为练习,因为它同样简单. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |