Implementar la clasificación definida por el usuario en SPARK

todo el mundo:

   ¡es bueno! La clasificación de datos en Spark se utiliza a menudo en el trabajo real. Este artículo implementa la clasificación definida por el usuario en forma de clases de muestra.

Preparar datos de muestra. Este es el primer paso. Estoy acostumbrado a poner los datos en un archivo. El directorio del archivo de prueba es C: \ test \ sort.txt, y los datos de muestra son los siguientes:

apple	5	5288
sansung	5	5888
huawei	1	3788
mi	4	3799
sony	3	3799
lg	4	2499

Descripción: 1 Los datos se separan según la tecla TAB. 2 Los datos de muestra tienen tres columnas (nombre del producto, peso, precio)

Primero use la clasificación de clasificación regular de Spark, el código es el siguiente:

package day04

import org.apache.spark.{SparkConf, SparkContext}

/**
  * Created by Administrator on 2017/9/24.
  * 功能: 演示用户自定义排序  自己写的两个sortBy 是不行的
  *
  */
object UserDefinedSort1 {
  def main(args: Array[String]): Unit = {
    val conf=new SparkConf().setAppName("UserDefinedSort1").setMaster("local[2]")
    val sc=new SparkContext(conf)
    val lines=sc.textFile("c://test//sort.txt")
    val rdd=lines.map(line=>{
      val f=line.split("\t")
      (f(0),f(1),f(2))
    })
    //    println(rdd.collect().toBuffer)
//       val sort=rdd.sortBy(_._2,true).sortBy(_._3,false)
    val sort=rdd.sortBy(_._2,true)
    val sort1=sort.sortBy(_._3,true)
    println(sort1.collect().toBuffer)
    sc.stop()


  }
}

Para verificar el efecto del experimento, hice los siguientes intentos, aquí solo intercepta el código central y los resultados para mostrar

val sort=rdd.sortBy(_._2,true)
println(sort.collect().toBuffer)

--true 结果  说明单个字段是按照从小到大的,其余字段没有参与排序
ArrayBuffer((huawei,1,3788), (sony,3,3799), (mi,4,3799), (lg,4,2499), (apple,5,5288), (sansung,5,5888))

val sort=rdd.sortBy(_._2,false)
println(sort.collect().toBuffer)

--false 结果 说明单个字段是按照从大到小的,其余字段没有参与排序 
ArrayBuffer((apple,5,5288), (sansung,5,5888), (mi,4,3799), (lg,4,2499), (sony,3,3799), (huawei,1,3788))
	
	
val sort=rdd.sortBy(_._2,false)
val sort1=sort.sortBy(_._3,false)
println(sort1.collect().toBuffer)

---先按照等级降序,再按照价格降序。 可以看到,没有按照预期的效果进行展现,似乎只有价格降序起了作用
ArrayBuffer((sansung,5,5888), (apple,5,5288), (mi,4,3799), (sony,3,3799), (huawei,1,3788), (lg,4,2499))


val sort=rdd.sortBy(_._2,true)
val sort1=sort.sortBy(_._3,false)
println(sort1.collect().toBuffer)

--先按照等级升序,在同一个等级内按照价格降序,可以看到,没有按照预期的效果进行展现,似乎只有价格降序起了作用
ArrayBuffer((sansung,5,5888), (apple,5,5288), (sony,3,3799), (mi,4,3799), (huawei,1,3788), (lg,4,2499))

val sort=rdd.sortBy(_._2,false)
val sort1=sort.sortBy(_._3,true)
println(sort1.collect().toBuffer)

---先按照等级降序,再按照价格升序, 可以看到,没有按照预期的效果进行展现,似乎只有价格升序起了作用
ArrayBuffer((lg,4,2499), (huawei,1,3788), (mi,4,3799), (sony,3,3799), (apple,5,5288), (sansung,5,5888))


val sort=rdd.sortBy(_._2,true)
val sort1=sort.sortBy(_._3,true)
println(sort1.collect().toBuffer)
	
---先按照等级升序,再按照价格升序,	可以看到,没有按照预期的效果进行展现,似乎只有价格升序起了作用
ArrayBuffer((lg,4,2499), (huawei,1,3788), (sony,3,3799), (mi,4,3799), (apple,5,5288), (sansung,5,5888))

Como puede ver, no hay ningún problema con un solo tipo. Sin embargo, si implica la clasificación de dos campos, existe un problema, que a menudo se requiere en el trabajo real.

Para ello, se introduce una clase de muestra y el código es el siguiente:

package day04

import org.apache.spark.{SparkConf, SparkContext}

/**
  * Created by Administrator on 2017/9/24.
  * 功能: 演示用户自定义排序  继承Ordered 类,重写compare方法
  *
  */
// 先定义一个样例类
case class Goods(val simi:Int,val price:Int) extends Ordered[Goods] with Serializable
{

  override def compare(that:Goods):Int={
    if(this.price==that.price){
      that.simi-this.simi   //如果价格相等,权重从大到小
    }else{
      this.price-that.price  //价格从小到大排序
    }

  }
}



object UserDefinedSort {
  def main(args: Array[String]): Unit = {
    val conf=new SparkConf().setAppName("UserDefinedSort").setMaster("local[2]")
    val sc=new SparkContext(conf)
    val lines=sc.textFile("c://test//sort.txt")
    val rdd=lines.map(line=>{
      val f=line.split("\t")
      (f(0),f(1).toInt,f(2).toInt)
    })
    val sort=rdd.sortBy(x=>Goods(x._2,x._3),true)

    println(sort.collect().toBuffer)


  }
}

Punto central: primero defina una clase de muestra para implementar la clase Ordered, reescriba el método de comparación y serialice

Los resultados del programa son los siguientes:

ArrayBuffer((lg,4,2499), (huawei,1,3788), (mi,4,3799), (sony,3,3799), (apple,5,5288), (sansung,5,5888))

Explicación: 1 Si cambia de verdadero a falso al ordenar en la línea 35 del programa, el resultado será el siguiente:

--false val sort=rdd.sortBy(x=>Goods(x._2,x._3),false)
ArrayBuffer((sansung,5,5888), (apple,5,5288), (sony,3,3799), (mi,4,3799), (huawei,1,3788), (lg,4,2499))

 En mi opinión, este método de escritura equivale a otra capa, que es fácil de confundir. Se recomienda escribir todas las reglas de clasificación en el método de comparación.

Supongo que te gusta

Origin blog.csdn.net/zhaoxiangchong/article/details/78409267
Recomendado
Clasificación