与zipwithIndex在groupbykey火花阶类型不匹配

问题描述 投票:0回答:1

我想测试groupByKey找对象的第n个最高分

我的数据是这样的

scala> a
res176: org.apache.spark.rdd.RDD[(String, String)] = MapPartitionsRDD[263] at map at <console>:51

scala> a.take(10).foreach{println}
(data science,DN,US,28,98,SMITH,data science)
(maths,DN,US,28,92,SMITH,maths)
(chemistry,DN,US,28,94,SMITH,chemistry)
(physics,DN,US,28,88,SMITH,physics)
(data science,DN,UK,25,93,JOHN,data science)
(maths,DN,UK,25,91,JOHN,maths)
(chemistry,DN,UK,25,95,JOHN,chemistry)
(physics,DN,UK,25,90,JOHN,physics)
(data science,DN,CA,29,67,MARK,data science)
(maths,DN,CA,29,68,MARK,maths)

scala> 

所以对于第一行“数据科学”的字符串是关键,“DN,美国,28,98,SMITH,数据科学”值作为字符串

现在我想找到第二个使用组最高

scala> a.groupByKey().flatMap(rec=>{ val max = rec._2.toList.map(x=>x.split(',')(3).toFloat).distinct.sortBy(x=>(-x)).zipWithIndex.filter(x=>x._2==2).toMap.keys
     | rec._2.toList.filter{x=>x.split(',')(3).toFloat==max}
     | }).take(15).foreach{println}

scala> 

我在这里得到什么

如果我运行这个硬编码,我得到的值

scala> a.groupByKey().flatMap(rec=>{ val max = "98"
     | rec._2.toList.sortBy(x=>(-x.split(',')(3).toFloat)).takeWhile(rec=> max.contains(rec.split(',')(3)))}).take(15).foreach{println}
DN,IND,26,98,XMAN,maths
DPS,US,28,98,XOMAN,chemistry
DN,US,28,98,SMITH,data science

这也给了我价值

scala> a.groupByKey().flatMap(rec=>{ rec._2.toList.map(x=>x.split(',')(3).toFloat).distinct.sortBy(x=>(-x)).zipWithIndex.filter(x=>x._2==2).map(_._1)}).take(15).foreach{println}
94.0
92.0
95.0
93.0

一些更复杂的代码给我输出

scala> a.groupByKey().flatMap(rec=>{ val max = rec._2.toList.map(x=>x.split(',')(3).toFloat).distinct.sortBy(x=>(-x)).take(1)
     | rec._2.toList.sortBy(x=>(-x.split(',')(3).toFloat)).takeWhile(rec=> max.contains(rec.split(',')(3).toFloat))}).take(15).foreach{println}
DN,IND,26,98,XMAN,maths
DPS,UK,25,96,SOMK,physics
DPS,US,28,98,XOMAN,chemistry
DN,US,28,98,SMITH,data science

貌似在我使用zipwithindex一些数据类型不匹配。可有一个人帮我在这里

scala apache-spark flatmap
1个回答
0
投票

还有由于.toMap.keys类型不匹配。在结果中,VAL max是类型可迭代[浮点]的,因为方法keys返回可迭代[A]。

该溶液的将是在head计算结束max的添加:

  val max = rec._2.toList
    .map(x => x.split(',')(3).toFloat)
    .distinct
    .sortBy(x => (-x))
    .zipWithIndex
    .filter(x => x._2 == 2)
    .toMap
    .keys
    .head

基本上,head将返回一个类型Float的值。然后,此代码应至少等于比较类型x.split(',')(3).toFloat == max

虽然,呼吁head是不是安全的方法。它可能会抛出一个异常,如果在你的情况下,filter函数可以返回空列表。那么这样会抛出异常:

java.util.NoSuchElementException: next on empty iterator

一旦混凝土数据采样工作,你能想到的重构这个代码可能与设置工作。相反head.keys.toSet和比较像你这样使用max.contains(rec.split(',')(3))其他例子

© www.soinside.com 2019 - 2024. All rights reserved.