RDD转换算子:排序算子:【sortBy、sortByKey】


1、sortBy:

功能:

对RDD中的所有元素进行整体排序,可以指定排序规则【按照谁排序,升序或者降序】

语法:

def sortBy(self, keyFunc:(T) -> 0, asc:bool,numPartitions) -> RDD

其中:

keyFunc:(T) -> 0:用于指定按照数据中的哪个值进行排序
asc: bool:用于指定升序还是降序,默认是升序

举例:

需求:

按照用户年龄降序排序:
文件内容如下:
laoda,20,male
laoer,22,female
laoliu,28,middle
laosan,24,male
laosi,30,male
laowu,26,female

排序结果如下:
laosi,30,male
laoliu,28,middle
laowu,26,female
laosan,24,male
laoer,22,female
laoda,20,male

代码:

fileRdd = sc.textFile("../../datas/c.txt")
fileRdd.sortBy(lambda line:line.split(",")[1],ascending=False).foreach(lambda line : print(line))

2、sortByKey:

功能:

对RDD中的所有元素按照Key进行整体排序,可以指定排序规则,只有KV类型的RDD才能调用

语法:

def sortByKey(self, asc, numPartitions) -> RDD[Tuple[K,V]]

举例:

rdd1 = sc.parallelize([("word", 10), ("word", 5), ("hello", 100), ("hello", 20), ("spark", 1)], numSlices=3)
rdd1.sortByKey(ascending=False).foreach(lambda x :print(x))
### Spark RDD中的二次排序实现 在Spark RDD中,二次排序是指基于多个键进行排序的过程。通常情况下,可以通过组合元组的方式完成这一目标。具体来说,在`sortBy`算子中传递一个复合键作为排序依据,从而实现多级排序。 以下是具体的实现方法: #### 实现思路 1. 将需要排序的字段封装成一个元组形式。 2. 利用`sortBy`算子对元组进行排序。 3. 如果需要自定义排序逻辑,则可以在Lambda表达式中提供相应的比较规则。 下面是一个完整的示例代码,展示如何在Scala和Python中分别实现二次排序。 --- ### Scala 示例代码 ```scala import org.apache.spark.{SparkConf, SparkContext} val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("SecondarySortExample") val sc: SparkContext = new SparkContext(conf) // 创建原始RDD val data = Array(("Alice", "Maths", 85), ("Bob", "Physics", 70), ("Charlie", "Chemistry", 90), ("David", "Biology", 60)) val rdd = sc.parallelize(data) // 定义复合键 (学科名称, 成绩),并转换为Tuple2[(String, Int), String] val mappedRdd = rdd.map { case (name, subject, score) => ((subject, -score), name) } // 使用sortBy对复合键进行排序(先按学科名升序,再按成绩降序) val sortedRdd = mappedRdd.sortBy(_._1) // 提取最终的结果 val result = sortedRdd.map { case (_, name) => name } println(result.collect.mkString(", ")) // 输出结果:David,Alice,Bob,Charlie sc.stop() ``` 在这个例子中,`(subject, -score)`被用来创建一个复合键,其中负号表示成绩部分按照降序排列[^1]。 --- ### Python 示例代码 ```python from pyspark import SparkContext sc = SparkContext("local", "SecondarySortExample") # 创建原始RDD data = [("Alice", "Maths", 85), ("Bob", "Physics", 70), ("Charlie", "Chemistry", 90), ("David", "Biology", 60)] rdd = sc.parallelize(data) # 定义复合键 (学科名称, -成绩),并映射为 Tuple((subject, -score), name) mapped_rdd = rdd.map(lambda x: ((x[1], -x[2]), x[0])) # 对复合键进行排序(先按学科名升序,再按成绩降序) sorted_rdd = mapped_rdd.sortByKey() # 提取最终的结果 result = sorted_rdd.map(lambda x: x[1]) print(result.collect()) # 输出结果 ['David', 'Alice', 'Bob', 'Charlie'] sc.stop() ``` 在此代码片段中,同样利用了`(subject, -score)`来构建复合键,并通过`sortByKey()`实现了二次排序[^2]。 --- ### 关于Shuffle优化 如果希望减少shuffle操作带来的性能开销,可以考虑使用`repartitionAndSortWithinPartitions`算子。此算子允许用户指定分区器以及排序规则,从而避免不必要的全局重排[^3]。 以下是一个简单的应用案例: ```scala import org.apache.spark.rdd.RDD import scala.math.Ordering val data = Array(("A", 1), ("B", 2), ("C", 3), ("D", 4)) val rdd: RDD[(String, Int)] = sc.parallelize(data) // 自定义排序规则 implicit val ordering = Ordering.by[(String, Int), Int](-_._2) // 调用 repartitionAndSortWithinPartitions 进行局部排序 val sortedRdd = rdd.repartitionAndSortWithinPartitions(new org.apache.spark.HashPartitioner(2)) println(sortedRdd.collect.mkString(", ")) ``` 在这里,`ordering`指定了基于第二列值的降序排序规则[^4]。 --- ### 总结 以上展示了两种主要的方法来进行Spark RDD的二次排序:一种是直接使用`sortBy`或`sortByKey`配合复合键;另一种则是借助`repartitionAndSortWithinPartitions`以降低shuffle成本。实际开发过程中可以根据需求选择合适的方案。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzhlizihang

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值