将Scala可变数组转换为spark数据帧

时间:2018-04-04 17:43:48

标签: scala spark-dataframe arraybuffer

我有三个可变数组定义为:

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作为数据帧提供 - 以便我可以进行进一步的连接。

1 个答案:

答案 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