基于spark-rank-scala的RDD元组第二和第三元素

基于spark-rank-scala的RDD元组第二和第三元素,scala,sorting,apache-spark,rdd,rank,Scala,Sorting,Apache Spark,Rdd,Rank,嗨,我想根据元组的第二个元素和第三个元素为每一行分配一个等级,这里有示例数据。如果元组的第三个元素具有针对id的最大值,则要添加“1”。如果元组的第三个元素具有相同的值,则基于元组的第二个元素,即第二个元素的最大值元组应具有“1”作为第四个元素。元组值的所有其他第四个元素都将为零。我希望您理解以下要求: (ID,Second,Third)->tuple (32609,878,199) (32609,832,199) (45470,231,199) (

嗨,我想根据元组的第二个元素和第三个元素为每一行分配一个等级,这里有示例数据。如果元组的第三个元素具有针对id的最大值,则要添加“1”。如果元组的第三个元素具有相同的值,则基于元组的第二个元素,即第二个元素的最大值元组应具有“1”作为第四个元素。元组值的所有其他第四个元素都将为零。我希望您理解以下要求:

    (ID,Second,Third)->tuple
    (32609,878,199)
    (32609,832,199)
    (45470,231,199)
    (42482,1001,299)
    (42482,16,291)
代码: *val Rank=matching.map{case(x1,x2,x3)=>(x1,x2,x3,((x3.toInt*100000)+x2.toInt.toInt)}.sortBy(-u4).groupBy(.\u1)*

结果:rank.take(10).foreach(println)

预期的产出将是:

(32609,878,199,1)
(32609,832,199,0)
(45470,231,199,1)
(42482,1001,299,1)
(42482,16,291,0)

似乎您可以尝试以下方法:

 val rank = matching.flatMap { case (x: String, y: String, z: String) => 
    val yInt = Try(y.toInt)
    val zInt = Try(z.toInt)
    if (yInt.isSuccess && zInt.isSuccess) Option((x, (yInt.get, zInt.get)))
    else None
 }.groupByKey().flatMap { case (key: String, tuples: Iterable[(Int, Int)]) =>
     val sorted = tuples.toList.sortBy(x => (-x._2, -x._1))
     val topRank = (key, sorted.head._1, sorted.head._2, 1)
     val restRank = for (tup <- sorted.tail) yield (key, tup._1, tup._2, 0)
     List(topRank) ++ restRank
 }
val rank=matching.flatMap{case(x:String,y:String,z:String)=>
val yInt=Try(y.toInt)
val zInt=Try(z.toInt)
if(yInt.issucess&&zInt.issucess)选项((x,(yInt.get,zInt.get)))
没有别的
}.groupByKey().flatMap{大小写(键:字符串,元组:Iterable[(Int,Int)])=>
val sorted=tuples.toList.sortBy(x=>(-x.\u 2,-x.\u 1))
val topRank=(键,已排序的.head.\u 1,已排序的.head.\u 2,1)

val restRank=for(tup这应该可以做到

对象应用程序{
def main(参数:数组[字符串]){
val sparkConf=new sparkConf().setAppName(“测试”).setMaster(“本地[4]”)
val sc=新的SparkContext(sparkConf)
val testData=列表((32609878199),
(32609,832,199),
(45470,231,199),
(42482,1001,299),
(42482,16,291))
val输入=sc.parallelize(测试数据)
val rank=input.groupBy(u._1).flatMapValues{
x=>
val sorted=x.toList.sortWith((x,y)=>x.2>y.2 | |(x.2==y.2&&x.3>y.3))
val first=sorted.head
(first.\u1,first.\u2,first.\u3,1)::sorted.tail.map(t=>(t.\u1,t.\u2,t.\u3,0))
}.map(u.u 2)
//将分区ID分配给每个项,以查看每个组是否已排序
val resultWithPartitionID=rank.mapPartitionsWithIndex((id,it)=>it.map(x=>(id,x)))
//打印RDD的内容时,不同分区的元素可能会交错
结果每个println的分区
val collectedResult=resultWithPartitionID.collect.sortBy(u._1).map(u._2)
//打印收集的结果
println(collectedResult.mkString(“\n”))
}
}
输出

(32609,878,199,1)
(32609,832,199,0)
(45470,231,199,1)
(42482,1001,299,1)
(42482,16,291,0)

“我希望你理解这个要求”不,至少我不明白。当你说“第二个元组”时,你是指“元组的第二个元素”——即
\u 2
?并且你还没有定义
id
@原型保罗,对不起……现在好了吗?我还不清楚。你说的“id的最大值”是什么意思?”?具有相同id的元组中所有第三个元素的最大值?我甚至不能分析这一点:“如果元组的第三个元素具有相同的值,那么基于元组的第二个元素,即第二个元素元组的最大值,应该将“1”作为第四个元素。”您的代码有一个100000,这在任何地方的需求中都没有提到。等等…现在没有时间编写它,但是使用reduceByKey来查找(element3,element2)的最大值。然后将其与原始rdd合并。然后映射,然后将最大值与当前元素2/3进行比较,如果匹配,则将元素4设置为1。这带来了一个问题-如果有两行具有相同id,并且元素2和元素3的最大值相同,会发生什么情况?令人印象深刻的代码@Rohan Aletty,非常感谢您的快速响应:)小排序顺序非常完美-**val sorted=tuples.toList.sortBy(x=>(-x.\u 2,-x.\u 1))**非常感谢。这是一个很好的观点!我对错误的排序顺序表示歉意。没问题,你做得很好:)
(32609,878,199,1)
(32609,832,199,0)
(45470,231,199,1)
(42482,1001,299,1)
(42482,16,291,0)