2017-10-18 81 views
0

我對Scala和Spark非常陌生,並且對於在輸出文件中顯示結果有一些疑問。以某種格式顯示輸出

其實,我在每個鍵關聯到的目錄列表(Map[Int, List<Double>])地圖,如:

(2, List(x1,x2,x3), List(y1,y2,y3), ...). 

我應該可以顯示每個鍵的值列出的名單裏,如:

2  x1,x2,x3 
2  y1,y2,y3 
1  z1,z2,z3 

等等。

當我使用saveAsTextFile函數時,它不會給出我想要的輸出結果。有人知道我能做到嗎?

編輯: 這是我的功能之一:

def PrintCluster(vectorsByKey : Map[Int, List[Double]], vectCentroidPairs : Map[Int, Int]) : Map[Int, List[Double]] = { 

    var vectorsByCentroid: Map[Int, List[Double]] = Map() 
    val SortedCentroid = vectCentroidPairs.groupBy(_._2).mapValues(x => x.map(_._1).toList).toSeq.sortBy(_._1).toMap 
    SortedCentroid.foreach { case (centroid, vect) => 
     var nbVectors = vect.length 

     for (i <- 0 to nbVectors - 1) { 
     var vectValues = vectorsByKey(vect(i)) 
     println(centroid + " " + vectValues) 
     vectorsByCentroid += (centroid -> (vectValues)) 
     } 
    } 
    return vectorsByCentroid 
    } 

我知道這是錯的,因爲我只能影響一個獨特的鍵一組值。這就是爲什麼它只返回Map中每個鍵的第一個List。我認爲使用saveAsTextFile函數,我必須使用Map結構,但我不知道。

+0

是什麼'saveAsTextFile'給你,它是如何從你想要什麼不同?此外,它看起來並不像你有列表的列表,但普通的列表('Map [Int,List [Double]]')? – Shaido

+0

您可能想要顯示您的Scala代碼。另外,嘗試使用CSV格式編寫數據集,但將分隔符設置爲選項卡 –

+0

@Shaido我擁有的輸出是邏輯,我的意思是...因爲我只能有一個值(地圖格式)的唯一鍵,所以只有第一個值被打印。這是我得到的:(3,List(-2.7,6.1,-2.8)),(2,List(-2.7,7.1,-2.8))。 – Sol

回答

0

使用Map[Int, List[List[Double]]]和簡單的格式打印出來想很簡單,它可以先完成轉換爲列表,然後應用flatMap。您在留言中提供的數據:

val map: Map[Int, List[List[Double]]] = Map(
    2 -> List(List(-4.4, -2.0, 1.5), List(-3.3, -5.4, 3.9), List(-5.8, -3.3, 2.3), List(-5.2, -4.0, 2.8)), 
    1 -> List(List(7.3, 1.0, -2.0), List(9.8, 0.4, -1.0), List(7.5, 0.3, -3.0), List(6.1, -0.5, -0.6), List(7.8, 2.2, -0.7), List(6.6, 1.4, -1.1), List(8.1, -0.0, 2.7)), 
    3 -> List(List(-3.0, 4.0, 1.4), List(-4.0, 3.9, 0.8), List(-1.4, 4.3, -0.5), List(-1.6, 5.2, 1.0)) 
) 

val list = map.toList.flatMap(t => t._2.map((t._1, _))) 
val result = for (t <- list) yield t._1 + "\t" + t._2.mkString(",") 

// Saving the result to file 
import java.io._ 
val pw = new PrintWriter(new File("fileName.txt")) 
result.foreach{ line => pw.println(line)} 
pw.close 

會打印出:

2 -4.4,-2.0,1.5 
2 -3.3,-5.4,3.9 
2 -5.8,-3.3,2.3 
2 -5.2,-4.0,2.8 
1 7.3,1.0,-2.0 
1 9.8,0.4,-1.0 
1 7.5,0.3,-3.0 
1 6.1,-0.5,-0.6 
1 7.8,2.2,-0.7 
1 6.6,1.4,-1.1 
1 8.1,-0.0,2.7 
3 -3.0,4.0,1.4 
3 -4.0,3.9,0.8 
3 -1.4,4.3,-0.5 
3 -1.6,5.2,1.0 
+0

它的工作原理!但不顯示任何東西作爲輸出...這是正常的嗎? – Sol

+0

@Sol它應該用'println()'打印行。包含的代碼,所以你也得到一個'List [String]'。 – Shaido

+0

我的意思是...我怎樣才能把這個算法放在saveAsTextFile中? – Sol

1

創建樣本RDD按你的輸入數據

val rdd: RDD[Map[Int, List[List[Double]]]] = spark.sparkContext.parallelize(
    Seq(Map(
    2 -> List(List(-4.4, -2.0, 1.5), List(-3.3, -5.4, 3.9), List(-5.8, -3.3, 2.3), List(-5.2, -4.0, 2.8)), 
    1 -> List(List(7.3, 1.0, -2.0), List(9.8, 0.4, -1.0), List(7.5, 0.3, -3.0), List(6.1, -0.5, -0.6), List(7.8, 2.2, -0.7), List(6.6, 1.4, -1.1), List(8.1, -0.0, 2.7)), 
    3 -> List(List(-3.0, 4.0, 1.4), List(-4.0, 3.9, 0.8), List(-1.4, 4.3, -0.5), List(-1.6, 5.2, 1.0))) 
) 
) 

變換RDD[Map[Int, List[List[Double]]]]RDD[(Int, String)]

val result: RDD[(Int, String)] = rdd.flatMap(i => { 
    i.map { 
    case (x, y) => y.map(list => (x, list.mkString(" "))) 
    } 
}).flatMap(z => z) 

result.foreach(println) 

result.saveAsTextFile("location") 
+0

不是。事實上,我有一個函數(void)爲每個Key打印值(x,y,z)。所以我知道它的工作原理。問題是我不知道如何返回正確的格式來顯示我想要的結果。如果我返回一個結果,它不能是一個映射,因爲一個映射有一個唯一的鍵,我有幾個值共享相同的鍵。這就是爲什麼我的輸出不能給我帶來好處。 這是我的最後幾行: 'VAL mapResult = PrintCluster(vectKeys,vectCentroidPair) sc.parallelize(mapResult.toSeq,2).saveAsTextFile( 「結果」)' – Sol

+0

您能查看編輯。如果不是,請嘗試添加示例輸入rdd。 – mrsrinivas

+0

對不起,我對我的正確代碼有點困惑。我編輯了我的帖子。事實上,我有兩個地圖真的很重要: 第一個:vectorsByKey,爲每個矢量匹配一個隨機密鑰,例如:Map(25,list(x,y,z))。第二個:vectCentroidPairs,根據其隨機密鑰值與匹配質心(K均值算法)匹配每個向量。我有這樣的東西:'Map(1,List(5,37,25,78,70,33,53,41,32,64,27))' 我要做的是檢索真實值(如此列表)下顯示每個匹配質心(1,2或3)。 – Sol