以某种格式显示输出

问题描述:

我对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

使用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

创建样本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