我有三个可变数组定义为:
import scala.collection.mutable.ArrayBuffer
var quartile_1 = ArrayBuffer[Double]()
var quartile_3 = ArrayBuffer[Double]()
var id = ArrayBuffer[String]()
quartile_1和quartile_3是id级别的信息,我目前正在将它们计算为:
def func1(x: org.apache.spark.sql.Row) {
val apQuantile = df_auth_for_qnt.where($"id" === x(0).toString).stat.approxQuantile("tran_amt", Array(0.25, 0.75), 0.001)
quartile_1 += apQuantile(0)
quartile_3 += apQuantile(1)
id += x(0).toString()
}
val cardNumList = df_auth_for_qnt_gb.where($"tran_cnt" > 8).select("card_num_1").collect.foreach(func1)
有没有比将它们附加到可变数组更好的方法?我的目标是将分位数据,id作为数据帧提供 - 以便我可以进行进一步的连接。
答案 0 :(得分:1)
像ArrayBuffer
这样的可变结构是邪恶的,特别是在可并行化的上下文中。在这里,他们可以很容易地避免。
func1
可以返回(String, Array[Double])
的元组,其中第一个元素对应于id(前id
缓冲区),第二个元素是从approxQuantile
返回的四分位数:
def func1(x: Row): (String, Array[Double]) = {
val cardNum1 = x(0).toString
val quartiles = df_auth_for_qnt.where($"id" === cardNum1).stat.approxQuantile("tran_amt", Array(0.25, 0.75), 0.001)
(cardNum1, quartiles)
}
现在,使用功能转换,我们可以获得不可变的结果结构。
作为DataFrame:
val resultDf = df_auth_for_qnt_gb.where($"tran_cnt" > 8).select("card_num_1").map(func1).toDF("id", "quartiles")
或者Map[String, Array[Double]]
与func1
返回的元组具有相同的关联:
val resultMap = df_auth_for_qnt_gb.where($"tran_cnt" > 8).select("card_num_1").map(func1).collect().toMap