Arrays 如何将一列数组转换为Spark中每个数组总和的列?

Arrays 如何将一列数组转换为Spark中每个数组总和的列?,arrays,scala,apache-spark,dataframe,Arrays,Scala,Apache Spark,Dataframe,我尝试过的每一种方法都给我留下了整个列的总和。每行都有一个填充了双精度的数组。我需要的是每行的一列总和 因此,您从一个如下所示的数据帧开始: id c2 c3 ------------------------- 1 1 [2.0, 1.0, 0.0] 2 2 [0.0, 0,0, 0.0] 因此,我希望: id c2 c3sum ------------------------- 1 1 3.0 2 2 0.0 在对“id”执行

我尝试过的每一种方法都给我留下了整个列的总和。每行都有一个填充了双精度的数组。我需要的是每行的一列总和

因此,您从一个如下所示的数据帧开始:

id   c2   c3
-------------------------
1     1   [2.0, 1.0, 0.0]
2     2   [0.0, 0,0, 0.0]
因此,我希望:

id   c2   c3sum
-------------------------
1     1   3.0
2     2   0.0
在对“id”执行
groupBy
之后,我尝试使用sum方法。我还尝试使用
udf

def mySum(arr:Seq[Double]):Double=arr.reduceLeft(_+_)
val dfsum = df.withColumn("c3sum", mySum($"c3"))
udf的这些和其他变体总是返回列中所有内容的总和。作为测试,我还尝试使用
array.max
只获取每个数组的最大值,而不是求和,它返回整个列的最大值。因此,这可能是一些我不理解的基本语法问题


提前感谢您的帮助。

一种可能的解决方案是使用
udf
(您已经尝试过)。要使其工作,您需要导入并使用
org.apache.spark.sql.functions.udf
来创建
udf
。工作示例:

import org.apache.spark.sql.functions.udf

val df = Seq(
    (1, 1, Seq(2.0, 1.0, 0.0)), 
    (2, 2, Seq(0.0, 0.0, 0.0)), 
    (3, 3, Seq(0.0, 1.0, 0.0))
).toDF("id", "c2", "c3")

val mySum = udf((arr: Seq[Double]) => arr.sum)
val dfsum = df.withColumn("c3sum", mySum($"c3"))
将提供:

+---+---+---------------+-----+
| id| c2|             c3|c3Sum|
+---+---+---------------+-----+
|  1|  1|[2.0, 1.0, 0.0]|  3.0|
|  2|  2|[0.0, 0.0, 0.0]|  0.0|
|  3|  3|[0.0, 1.0, 0.0]|  1.0|
+---+---+---------------+-----+

您可能想考虑使用<代码>数据集<代码> >代码> map < /COD> > <代码>和>代码>,而不是依赖于UDF:

import org.apache.spark.sql.functions._

val df = Seq(
  (1, 1, Array(2.0, 1.0, 0.0)),
  (2, 2, Array(0.0, 0.0, 0.0))
).toDF("id", "c2", "c3")

df.
  withColumn("c3", coalesce($"c3", lit(Array[Double]()))).
  as[(Int, Int, Array[Double])].
  map{ case (id, c2, c3) => (id, c2, c3.sum) }.
  toDF("id", "c2", "c3sum").
  show

// +---+---+-----+
// | id| c2|c3sum|
// +---+---+-----+
// |  1|  1|  3.0|
// |  2|  2|  0.0|
// +---+---+-----+

请注意,在转换为数据集之前,
coalesce
应用于c3,以将
null
(如果有)替换为空数组[Double]。

为什么要将默认值更改为val?性能有改进吗?我';不管怎样,我对在两者之间做出选择感到困惑。说出来';s def每个分区只计算一次,然后序列化并发送到工作节点@谢谢你的建议。它对我的数据帧不起作用,但我认为问题在我这边。仍在尝试解决。@Thugnitive:这应该可以,所以数据可能有问题?你犯了什么错误?@Shaido没有任何错误。它总是只返回一个或两个值。我在本专栏中有数千个数组,大多数只是[0,0,0,0…],但有一些数组的值不是零值。在转换之前,df.distinct.show()显示许多行,但在运行聚合之后,我总是得到df.distinct.count()==2。这两个值是“0.0”和所有其他值的总和。@Thougnificent:添加了一个工作示例,您可以试试它是否适合您。像这样使用udf应该不会对行数产生任何影响,您是否对数据做了更多的处理?测试用例可以工作,但对我的数据帧不起作用。我的数据一定有什么不寻常的地方。@Thugnitive,不确定您的实际数据有什么错误。我已将答案更新为在数组列中处理
null
s,以防万一这就是原因。