Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用spark进行分类_Java_Sorting_Apache Spark_Distributed Computing - Fatal编程技术网

Java 使用spark进行分类

Java 使用spark进行分类,java,sorting,apache-spark,distributed-computing,Java,Sorting,Apache Spark,Distributed Computing,我需要对RDD进行排序。排序需要在我记录的多个字段上,因此我需要一个自定义比较器 我看到排序为,因为它只接受一个键。我偶然发现并因此使用了重新分区和sortwithintitions来实现同样的效果 为什么sortBy不接受自定义比较器和排序?为什么我必须重新分配才能使用自定义比较器?问题1:这是方法的签名,sortBy: /** * Return this RDD sorted by the given key function. */ def sortBy[K](

我需要对RDD进行排序。排序需要在我记录的多个字段上,因此我需要一个自定义比较器

我看到
排序为
,因为它只接受一个键。我偶然发现并因此使用了
重新分区和sortwithintitions
来实现同样的效果


为什么
sortBy
不接受自定义比较器和排序?为什么我必须重新分配才能使用自定义比较器?

问题1:这是方法
签名,sortBy

  /**
   * Return this RDD sorted by the given key function.
   */
  def sortBy[K](
      f: (T) => K,
      ascending: Boolean = true,
      numPartitions: Int = this.partitions.length)
      (implicit ord: Ordering[K], ctag: ClassTag[K]): RDD[T] = withScope {
    this.keyBy[K](f)
        .sortByKey(ascending, numPartitions)
        .values
  }
显然,您的RDD数据对象是T类型的

请注意,sortBy方法绝对只有一个关键参数字段:
f:(T)=>K

它接受一个匿名函数,因此您可以轻松生成自定义的可比较结构,并充分利用具有自己定义良好的比较器的常见数据类型

例如,如果您的RDD[Int,Int],我们称之为数据,您可以执行以下操作:

val cmp = (t: (Int, Int)) => (t._1, -t._2)
data.sortBy(cmp)
这可以轻松实现多字段比较,对吗?

这将得到一个带有第一个字段ascend和第二个字段的排序RDD 下降

问题2:重新分区和排序分区用法

这是一个特定的rdd操作符,旨在比调用重新分区然后在每个分区内排序更有效

您的程序在排序之前不需要预先重新分区,它只是在这个特定的公共模式下进行内部优化,以获得高性能

详情请参阅

  • mapPartitions,以使用对每个分区进行排序,例如,.sorted
  • 重新分区和SortWithinPartitions可有效地对分区进行排序 同时进行重新分区
  • sortBy要进行全局排序 RDD
  • RDD的sortByKey方法用于总订购

  • RDD的repartitionAndSortWithinPartitions在分区内使用排序,但不跨分区使用排序,但不幸的是,它添加了一个额外的步骤来进行重新分区

如Spark API中所述,repartitionAndSortWithinPartitions比调用repartition然后在每个分区内排序更有效,其他单词repartitionAndSortWithinPartitions将首先基于提供的分区器重新分区数据,然后按键排序:

所以,首先重新分区,然后再打电话给sortBy,这会给您带来良好的性能 使用重新分区和SortWithinPartitions可以实现相同的效果

添加一些排序示例希望能有所帮助

例1

结果:

rdd: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[101] at parallelize at command-1784487111427703:1
sorted1: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[104] at sortByKey at command-1784487111427703:12
sorted3: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[110] at sortByKey at command-1784487111427703:34
res28: Array[(String, Int)] = Array((science,59), (science,54), (math,55), (math,56), (english,57), (english,58))
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
case class MyRecord(time: Double, id: String)
val rdd = sc.parallelize(1 to 200, 200).flatMap(x =>Seq.fill(10000)(MyRecord(util.Random.nextDouble, "xxx")))
// sort this RDD by time:
val sorted = rdd.sortBy(x => x.time)
result.count

// convert the original RDD to Dataframe and sort again:
val df = sqlContext.createDataFrame(rdd)
df.registerTempTable("data")
val result = sqlContext.sql("select * from data order by time")
result.count
例2

RDD与数据集:

rdd: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[101] at parallelize at command-1784487111427703:1
sorted1: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[104] at sortByKey at command-1784487111427703:12
sorted3: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[110] at sortByKey at command-1784487111427703:34
res28: Array[(String, Int)] = Array((science,59), (science,54), (math,55), (math,56), (english,57), (english,58))
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
case class MyRecord(time: Double, id: String)
val rdd = sc.parallelize(1 to 200, 200).flatMap(x =>Seq.fill(10000)(MyRecord(util.Random.nextDouble, "xxx")))
// sort this RDD by time:
val sorted = rdd.sortBy(x => x.time)
result.count

// convert the original RDD to Dataframe and sort again:
val df = sqlContext.createDataFrame(rdd)
df.registerTempTable("data")
val result = sqlContext.sql("select * from data order by time")
result.count

我使用Java,我不认为我可以编写一个等价于
valcmp=(t:(Int,Int))=>(t._1,-t._2)
。Java中的
sortBy
只允许我选择一个用于排序的键。请参照此,,