[英]Order Spark RDD based on ordering in another RDD
我有一个带有这样的字符串的RDD(以特定方式排序):
["A","B","C","D"]
另一个 RDD 列表如下:
["C","B","F","K"],
["B","A","Z","M"],
["X","T","D","C"]
我想根据它们在第一个 RDD 中出现的顺序对第二个 RDD 中每个列表中的元素进行排序。 没有出现在第一个列表中的元素的顺序无关紧要。
从上面的例子中,我想得到一个这样的 RDD:
["B","C","F","K"],
["A","B","Z","M"],
["C","D","X","T"]
我知道在处理第二个 RDD 中的每个列表时,我应该使用广播变量来广播第一个 RDD。 但我对 Spark/Scala(以及一般的函数式编程)非常陌生,所以我不确定如何做到这一点。
我假设第一个 RDD 很小,因为您谈论广播它。 在这种情况下,您是对的,广播订购是解决您的问题的好方法。
// generating data
val ordering_rdd = sc.parallelize(Seq("A","B","C","D"))
val other_rdd = sc.parallelize(Seq(
Seq("C","B","F","K"),
Seq("B","A","Z","M"),
Seq("X","T","D","C")
))
// let's start by collecting the ordering onto the driver
val ordering = ordering_rdd.collect()
// Let's broadcast the list:
val ordering_br = sc.broadcast(ordering)
// Finally, let's use the ordering to sort your records:
val result = other_rdd
.map( _.sortBy(x => {
val index = ordering_br.value.indexOf(x)
if(index == -1) Int.MaxValue else index
}))
请注意,如果在列表中找不到该元素, indexOf
返回-1
。 如果我们保持原样,所有未找到的元素都将在开头结束。 我知道你最后想要它们,所以我将-1
调整为一个大数字。
打印结果:
scala> result.collect().foreach(println)
List(B, C, F, K)
List(A, B, Z, M)
List(C, D, X, T)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.