如何使用Spark-Scala中的takeOrdered(4)(Ordering[Int])
方法對2列或多列進行排序。如何使用takeOrdered對多個列進行排序?
此使用sortBy這樣我可以實現:
lines.sortBy(x => (x.split(",")(1).toInt, -x.split(",")(4).toInt)).map(p => println(p)).take(50)
但是當我嘗試使用takeOrdered接近其未能
如何使用Spark-Scala中的takeOrdered(4)(Ordering[Int])
方法對2列或多列進行排序。如何使用takeOrdered對多個列進行排序?
此使用sortBy這樣我可以實現:
lines.sortBy(x => (x.split(",")(1).toInt, -x.split(",")(4).toInt)).map(p => println(p)).take(50)
但是當我嘗試使用takeOrdered接近其未能
排序您可以實現自定義排序:
lines.takeOrdered(4)(new Ordering[String] {
override def compare(x: String, y: String): Int = {
val xs=x.split(",")
val ys=y.split(",")
val d1 = xs(1).toInt - ys(1).toInt
if (d1 != 0) d1 else ys(4).toInt - xs(4).toInt
}
})
tl; dr做一些這樣的事情(但是考慮重寫你的代碼來調用split
一次):
lines.map(x => (x.split(",")(1).toInt, -x.split(",")(4).toInt)).takeOrdered(50)
這裏是解釋。
當你調用takeOrdered
直接lines
,生效的implicit Ordering
是Ordering[String]
因爲lines
是RDD[String]
。您需要將lines
轉換爲新的RDD[(Int, Int)]
。因爲有implicit Ordering[(Int, Int)]
可用,它會在您的轉換RDD
上生效。
同時,sortBy
的工作原理有所不同。下面是簽名:
sortBy[K](f: (T) ⇒ K, ascending: Boolean = true, numPartitions: Int = this.partitions.length)(implicit ord: Ordering[K], ctag: ClassTag[K]): RDD[T]
我知道這是一個令人生畏的簽名,但如果你通過削減噪音,你可以看到sortBy
需要您的原始類型映射到一個新的類型只是排序目的的功能,如果其中一個在implicit
範圍內,則適用於該返回類型的Ordering
。
在你的情況,你在你的RDD
應用功能的String
s到它們轉變成如何星火應該僅僅把它們用於排序目的「視圖」,即爲(Int, Int)
,然後依靠implicit Ordering[(Int, Int)]
如上所述可用。
的sortBy
方法可以讓你保持lines
完整爲RDD[String]
和使用映射只是進行排序,而takeOrdered
方法上全新RDD
,包含從原始lines
衍生(Int, Int)
工作。哪種方法更適合您的需求取決於您希望完成什麼。
在另一個說明中,您可能想要將您的代碼重寫爲只有split
您的文本一次。
'線條'的類型是什麼? –