将Scala方法转换为Spark

将Scala方法转换为Spark,scala,apache-spark,Scala,Apache Spark,下面的Scala方法返回数组的k个最近邻: def getNearestNeighbours(distances: Array[((String, String), Double)], k: Int, label: String) = { //| label: String)List[((String, String), Double)] distances.filter(v => v._1._1.equals(label) || v._

下面的Scala方法返回
数组的k个最近邻:

  def getNearestNeighbours(distances: Array[((String, String), Double)], k: Int, label: String) = {                    //| label: String)List[((String, String), Double)]

    distances.filter(v => v._1._1.equals(label) || v._1._2.equals(label)).sortBy(_._2).take(k)
  }
我想并行运行这个函数。我可以尝试将
数组
转换为
RDD
,但type
RDD
不支持函数
。sortBy(u._2)。take(k)
有没有办法在Spark/Scala中模拟此方法

一个可能的解决方案是修改该方法,以便每次调用该方法时都将RDD转换为数组,但我认为对于大型RDD来说,这在计算上是昂贵的:

  def getNearestNeighbours(distances: RDD[((String, String), Double)], k: Int, label: String) = {                    //| label: String)List[((String, String), Double)]

    distances.collect.filter(v => v._1._1.equals(label) || v._1._2.equals(label)).sortBy(_._2).take(k)
  }

RDD确实有
sortByKey
方法,该方法按第一个元素对成对RDD进行排序,因此如果您可以创建
RDD[(Double,(String,String))]
而不是
RDD[((String,String),Double)]
(或者只需调用
RDD.map(p=>(p.\u 2,p.\u 1)
),您可以直接翻译算法。它也有
take
,但文档中说:

返回一个包含数据集前n个元素的数组。请注意,该数组当前不是并行执行的。而是由驱动程序计算所有元素

所以我不认为这能很好地工作

此外,如果数据放在一台机器上,仅使用数组(或并行集合)可能会更快。Spark尽其所能减少开销,但分布式排序无论如何都会有一些开销


此外,如果只需要最少的
n
元素,则对整个数组/RDD/其他集合进行排序是一个坏主意(同样,尤其是在需要使用Spark的情况下)。您需要像或中所述的选择算法。不幸的是,它们在Scala标准库或Spark(据我所知)中不可用,您可以直接翻译算法。它也有
take
,但文档中说:

返回一个包含数据集前n个元素的数组。请注意,该数组当前不是并行执行的。而是由驱动程序计算所有元素

所以我不认为这能很好地工作

此外,如果数据放在一台机器上,仅使用数组(或并行集合)可能会更快。Spark尽其所能减少开销,但分布式排序无论如何都会有一些开销


此外,如果只需要最少的
n
元素,则对整个数组/RDD/其他集合进行排序是一个坏主意(同样,尤其是在需要使用Spark的情况下)。您需要像或中所述的选择算法。不幸的是,它们在Scala标准库或Spark(据我所知)中不可用,您可以直接翻译算法。它也有
take
,但文档中说:

返回一个包含数据集前n个元素的数组。请注意,该数组当前不是并行执行的。而是由驱动程序计算所有元素

所以我不认为这能很好地工作

此外,如果数据放在一台机器上,仅使用数组(或并行集合)可能会更快。Spark尽其所能减少开销,但分布式排序无论如何都会有一些开销


此外,如果只需要最少的
n
元素,则对整个数组/RDD/其他集合进行排序是一个坏主意(同样,尤其是在需要使用Spark的情况下)。您需要像或中所述的选择算法。不幸的是,它们在Scala标准库或Spark(据我所知)中不可用,您可以直接翻译算法。它也有
take
,但文档中说:

返回一个包含数据集前n个元素的数组。请注意,该数组当前不是并行执行的。而是由驱动程序计算所有元素

所以我不认为这能很好地工作

此外,如果数据放在一台机器上,仅使用数组(或并行集合)可能会更快。Spark尽其所能减少开销,但分布式排序无论如何都会有一些开销


此外,如果只需要最少的
n
元素,则对整个数组/RDD/其他集合进行排序是一个坏主意(同样,尤其是在需要使用Spark的情况下)。您需要像或中所述的选择算法。不幸的是,它们在Scala标准库或Spark(据我所知)中不可用

不要
收集
RDD。它将所有数据拉到一台机器上。更改输入,使其按负距离(
RDD[Double,(String,String)]
)键入,然后使用
RDD.top(k)

不要
收集
RDD。它将所有数据拉到一台机器上。更改输入,使其按负距离键入(
RDD[Double,(String,String)]
),然后使用
RDD.top(k)
不要
收集
RDD.It