[英]How to pass one RDD in another RDD through .map
我有兩個rdd,我想對rdd1的每個項目的RDD2項目進行一些計算。 所以,我在用戶定義的函數中傳遞RDD2,如下所示,但我得到的錯誤就像rdd1 cannot be passed in another rdd
。 如果我想在兩個rdd上執行操作,我可以知道如何實現這個目的嗎?
例如:
RDD1.map(line =>function(line,RDD2))
錯誤說明,Spark不支持嵌套RDD。 通常你必須通過重新設計算法來繞過它。
如何做到這取決於實際的用例, function
中究竟發生了什么以及它的輸出是什么。
有時RDD1.cartesian(RDD2)
,每個元組執行操作然后按鍵減少將起作用。 有時,如果你有(K,V)
類型,兩個RDD之間的連接將起作用。
如果RDD2很小,你總是可以在驅動程序中收集它,使它成為一個廣播變量,並在function
使用該變量而不是RDD2
。
@編輯:
例如,假設您的RDD持有字符串, function
將計算RDD
中給定RDD
記錄的RDD2
:
def function(line: String, rdd: RDD[String]): (String, Int) = {
(line, rdd.filter(_ == line).count)
}
這將返回RDD[(String, Int)]
。
Idea1
您可以嘗試使用RDD的cartesian
方法使用笛卡爾積 。
val cartesianProduct = RDD1.cartesian(RDD2) // creates RDD[(String, String)]
.map( (r1,r2) => (r1, function2) ) // creates RDD[(String, Int)]
.reduceByKey( (c1,c2) => c1 + c2 ) // final RDD[(String, Int)]
這里function2
取r1
和r2
(它們是字符串),如果相等則返回1
否則返回0
。 最終的映射將產生一個RDD
,它將具有元組,其中鍵將是來自r1
的記錄,值將是總計數。
問題1:如果你在RDD1
有重復的字符串,這將不起作用。 你必須考慮一下。 如果RDD1
記錄有一些完美的唯一ID。
問題2:這確實創造了很多對(對於兩個RDD中的1mln記錄,它將創建大約500bln對),會很慢並且很可能導致大量的混亂 。
Idea2
我不明白關於RDD2的大小您的評論lacs
所以這可能或可能無法正常工作:
val rdd2array = sc.broadcast(RDD2.collect())
val result = RDD1.map(line => function(line, rdd2array))
問題:這可能會炸毀你的記憶。 在driver
上調用collect()
, rdd2
all
記錄加載到驅動程序節點上的內存中。
Idea3
根據用例,還有其他方法可以解決這個問題,例如,相似性搜索的強力算法與您的用例類似(不是意圖)。 對此的替代解決方案之一是Locality Sensitive Hashing 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.