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,以防万一这就是原因。