[英]RDD accessing values in another RDD
我有一個RDD
需要從另一個訪問數據RDD
。 但是,我總是得到一個Task not Serializable
錯誤。 我已經擴展了Serializable
類,但它沒有工作。 代碼是:
val oldError = rddOfRatings.aggregate(0.0)((accum, rating) =>
accum + calcError(rating.rating,
us.lookup(rating.user)(0),
it.lookup(rating.product)(0)).abs, _+_ ) / rddSize
在us
, it
和rddOfRatings
是另一個RDD
的。 我不明白的是,如果一個RDD
是不可改變的,那么為什么不會它讓我允許訪問的RDD
從另一個內RDD
? 問題似乎在於us
和it
一樣,當我為本地集合刪除it
時,它工作正常。
謝謝。
由於必須捕獲的變量(例如SparkContext),RDD確實是不可序列化的。 要解決這個問題,將三個RDD連接在一起,您將在累加器閉包中獲得所有必要的值。
rdd.lookup
1是一項昂貴的操作,即使可以,也可能不想做。
此外,“序列化”RDD沒有意義,因為RDD只是對數據的引用,而不是數據本身。
這里采取的方法可能取決於這些數據集的大小。 如果us
和it
RDD大小與rddOfRatings
大小相同(考慮到預期的查找,它看起來是這樣的),最好的方法是事先加入它們。
//請注意我不知道你的收藏品的實際結構,所以把它作為一個說明性的例子
val ratingErrorByUser = us.map(u => (u.id, u.error))
val ratingErrorByProduct = it.map(i=> (i.id, i.error))
val ratingsBykey = rddOfRatings.map(r=> (r.user, (r.product, r.rating)))
val ratingsWithUserError = ratingsByKey.join(ratingErrorByUser)
val ratingsWithProductError = ratingsWithUserError.map{case (userId, ((prodId, rating),userErr))} => (prodId,(rating, userErr))}
val allErrors = ratingsWithProductError.join(ratingErrorByProduct)
val totalErr = allErrors.map{case (prodId,((rating, userErr),prodErr)) => calcError(userErr, math.abs(prodErr), rating)}.reduce(_+_)
val total = totalErr / rddOfRatings.count
使用Spark DataFrame API可能會更容易
1 ,如果查找是必須的(不像在這種情況下!),看看星火IndexedRdd
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.