簡體   English   中英

Apache Spark的RDD [Vector]不變性問題

[英]Apache Spark's RDD[Vector] Immutability issue

我知道RDD是不可變的,因此不能更改其值,但是我看到以下行為:

我為FuzzyCMeans( https://github.com/salexln/FinalProject_FCM )算法編寫了一個實現,現在我正在對其進行測試,因此我運行以下示例:

import org.apache.spark.mllib.clustering.FuzzyCMeans
import org.apache.spark.mllib.linalg.Vectors

val data = sc.textFile("/home/development/myPrjects/R/butterfly/butterfly.txt")
val parsedData = data.map(s => Vectors.dense(s.split(' ').map(_.toDouble))).cache()
> parsedData: org.apache.spark.rdd.RDD[org.apache.spark.mllib.linalg.Vector] = MapPartitionsRDD[2] at map at <console>:31

val numClusters = 2
val numIterations = 20


parsedData.foreach{ point => println(point) }
> [0.0,-8.0]
[-3.0,-2.0]
[-3.0,0.0]
[-3.0,2.0]
[-2.0,-1.0]
[-2.0,0.0]
[-2.0,1.0]
[-1.0,0.0]
[0.0,0.0]
[1.0,0.0]
[2.0,-1.0]
[2.0,0.0]
[2.0,1.0]
[3.0,-2.0]
[3.0,0.0]
[3.0,2.0]
[0.0,8.0] 

val clusters = FuzzyCMeans.train(parsedData, numClusters, numIteration
parsedData.foreach{ point => println(point) }
> 
[0.0,-0.4803333185624595]
[-0.1811743096972924,-0.12078287313152826]
[-0.06638890786148487,0.0]
[-0.04005925925925929,0.02670617283950619]
[-0.12193263222069807,-0.060966316110349035]
[-0.0512,0.0]
[NaN,NaN]
[-0.049382716049382706,0.0]
[NaN,NaN]
[0.006830134553650707,0.0]
[0.05120000000000002,-0.02560000000000001]
[0.04755220304297078,0.0]
[0.06581619798335057,0.03290809899167529]
[0.12010867103812725,-0.0800724473587515]
[0.10946638900458144,0.0]
[0.14814814814814817,0.09876543209876545]
[0.0,0.49119985188436205] 

但是我的方法如何更改不可變RDD?

BTW,火車方法的簽名,如下所示:

火車(數據:RDD [Vector],簇:Int,maxIterations:Int)

您所做的工作在docs中進行了精確描述:

RDD的打印元素

另一個常見用法是嘗試使用rdd.foreach(println)或rdd.map(println)打印出RDD的元素。 在單台機器上,這將生成預期的輸出並打印所有RDD的元素。 但是,在集群模式下,執行者正在調用stdout的輸出現在正在寫入執行者的stdout,而不是驅動程序上的那個,因此驅動程序上的stdout不會顯示這些內容! 要在驅動程序上打印所有元素,可以使用collect()方法首先將RDD帶到驅動程序節點:rdd.collect()。foreach(println)。 但是,這可能會導致驅動程序用盡內存,因為collect()將整個RDD提取到一台計算機上。 如果只需要打印RDD的一些元素,則更安全的方法是使用take():rdd.take(100).foreach(println)。

因此,由於數據可以在節點之間遷移,因此不能保證foreach的相同輸出。 RDD是不可變的,但是您應該以適當的方式提取數據,因為您的節點上沒有整個RDD。


另一個可能的問題(而不是在你的情況為你使用一個不變的向量)使用可變數據里面Point iself,這是完全不正確,那么你會失去一切保障-在RDD本身仍然會成為不可改變但是。

為了使RDD完全不可變,其內容也應該不可變:

scala> val m = Array.fill(2, 2)(0)
m: Array[Array[Int]] = Array(Array(0, 0), Array(0, 0))

scala> val rdd = sc.parallelize(m)
rdd: org.apache.spark.rdd.RDD[Array[Int]] = ParallelCollectionRDD[1]
at parallelize at <console>:23

scala> rdd.collect()
res6: Array[Array[Int]] = Array(Array(0, 0), Array(0, 0))

scala> m(0)(1) = 2

scala> rdd.collect()
res8: Array[Array[Int]] = Array(Array(0, 2), Array(0, 0)) 

所以因為Array是可變的,所以我可以更改它,因此RDD已用新數據更新

暫無
暫無

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

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