簡體   English   中英

Scala Spark過濾器內部地圖

[英]Scala Spark filter inside map

我想在映射時有效地過濾RDD。 那可能嗎?

這是我想要做的偽代碼:

for element in rdd:
    val opt = f(element)
    if (opt.nonEmpty) add_pair(opt.get, element)

這是在Scala Spark中實現偽代碼的一種hacky方法:

rdd.map(element => (
    f(element).getOrElse(99),
    element
)).filter(tuple => tuple._1 != 99)

我無法找到干凈的語法來做到這一點,所以我首先映射所有元素,然后過濾掉我不想要的。 請注意,可能昂貴的調用f(element)僅計算一次。 如果我在映射之前過濾元素(看起來會更干凈),那么我最終會調用f兩次,效率很低。

請不要將此標記為重復。 雖然有類似的問題,但實際上沒有人回答這個問題。 例如, 這個潛在的副本將調用f兩次,這是低效的,因此不回答這個問題。

你可以使用flatMap

//let's say your f returns Some(x*2) for even number and None for odd
def f(n: Int): Option[Int] = if (n % 2) Some(n*2) else None 

val rdd = sc.parallelize(List(1,2,3,4))
rdd.flatMap(f) // 4,8

// rdd.flatMap(f) or rdd.flatMap(f(_)) or rdd.flatMap(e => f(e))

如果你需要進一步傳遞元組並過濾,那么只需使用嵌套map

rdd.flatMap(e => f(e).map((_,e))) //(4,2),(8,4)

您可以使用mapPartitions進行過濾以及昂貴的計算。

rdd.mapPartitions( elements => 
  elements
      .map(element => (f(element),element))
      .filter(tuple => tuple._1.isDefined)
)

請注意,在此代碼中, filter是本機scala集合方法,而不是Spark RDD過濾器。

或者,您也可以flatMap映射函數的結果

rdd.flatMap(element => f(element).map(result => (result,element)))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM