spark编程实战(二) —— 中位数

最近正在看《Spark大数据处理:技术、应用与性能优化》这本书,然后对于最后一章的编程实战比较感兴趣。但是上面写的算法个人觉得还不是很简洁,无法体现出scala的优点,所以稍作了一些修改,仅供参考。

设计思路
海量数据求中位数有很多解决方案。 假设海量数据已经预先排序本例的解决方案为:将
整个数据空间划分为K个桶。 第一轮,在mapPartition阶段先将每个分区内的数据划分为K个
桶,统计桶中的数据量,然后通过reduceByKey聚集整个RDD每个桶中的数据量。 第二轮,
根据桶统计的结果和总的数据量,可以判读数据落在哪个桶里,以及中位数的偏移量
(offset)。 针对这个桶的数据进行排序或者采用Top K的方式,获取到偏移为offset的数
据。

代码实现:

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

object Wedian {


  def main(args: Array[String]): Unit = {

    val conf = new SparkConf()
      .setAppName("Wedian")
      .setMaster("local")

    val sc = new SparkContext(conf)
    //读取数据
    val dataRDD = sc.textFile("./data/num.txt")
      .flatMap(_.split(" "))
      .map(x => x.toInt)
    //将一定范围内的数据分区,比如数据1,2,3,4,5,6 如果num/4会将1,2,3放入一个分区,4放入一个分区,5,6放入一个分区。相当于将归并,减少计算量,切记不能用求余,目的为了保证数据的有序性。
    val mappedDataRDD = dataRDD.map(num => (num / 4, num))
      .sortByKey()
    //统计每个分区元素个数
    val countRDD = dataRDD.map(num => (num / 4, 1))
      .reduceByKey((a, b) => (a + b)).sortByKey()

    //将RDD转换成map形式,用于后续计算
    val data_count = countRDD.collectAsMap()
    //计算元素总个数
    val sum = data_count.map(s => s._2).sum
    
    //中位数所在分区的末尾元素的偏移量
    var temp = 0
    //中位数前一个分区的末尾元素的偏移量
    var temp_1 = 0
    //所处在第几个分区
    var index = 0
    //中位数的偏移量
    var mid = 0
    //计算中位数在整个元素的位置
    if (sum % 2 != 0) mid = sum / 2 + 1 else mid = sum / 2
    
    //分区总个数
    val count = countRDD.count()

    var flag = 1
    //scala中没有break语句,所以利用守卫跳出循环
    for (i <- 0 to count.toInt - 1 if flag == 1) {
      temp = temp + data_count(i)
      temp_1 = temp - data_count(i)
      if (mid <= temp) {
        index = i
        flag = 0
      }
    }
    
    println(mid +" "+ index +" "+temp+" "+temp_1)
    //计算中位数在当前分区的偏移量
    val offset = mid - temp_1
    //利用过滤将这个分区内的所有数取出来,将中位数以前的该分区内的所有数取出来,再取最后一个数既是中位数
    val result = mappedDataRDD.filter(x => x._1 == index).takeOrdered(offset)

    println(result(offset-1)._2)
    
    sc.stop()
  }
}

引用\[1\]:在过去的两个月里,Databricks公司举办了一场会议,将数据团队聚集在一起,共召开220多个会议,有无数机会与同行交流——超过50,000名数据科学家、数据工程师、分析师、商业领袖和其他数据专业人士。 Spark + AI 峰会虚拟环境。 引用\[2\]:本书以数据智能为灵魂,以Spark 2.4.X版本为载体,以Spark+ AI商业案例实战和生产环境下几乎所有类型的性能调优为核心,对企业生产环境下的Spark+AI商业案例与性能调优抽丝剥茧地进行剖析。全书共分4篇,内核解密篇基于Spark源码,从一个实战案例入手,循序渐进地全面解析Spark 2.4.X版本的新特性及Spark内核源码;商业案例篇选取Spark开发中最具代表性的经典学习案例,在案例中综合介绍Spark的大数据技术;性能调优篇覆盖Spark在生产环境下的所有调优技术; Spark+ AI内幕解密篇讲解深度学习动手实践,通过整合Spark、PyTorch以及TensorFlow揭秘Spark上的深度学习内幕。本书适合所有大数据和人工智能学习者及从业人员使用。对于有丰富大数据和AI应用经验的人员,本书也可以作为大数据和AI高手修炼的参考用书。同时,本书也特别适合作为高等院校的大数据和人工智能教材。 问题:spark数据分析实战——奥运会 回答: Spark是一个强大的大数据处理框架,可以用于数据分析和处理。在奥运会数据分析实战中,Spark可以帮助我们处理大规模的奥运会数据,进行数据清洗、转换和分析。通过使用Spark的分布式计算能力和优化技术,我们可以高效地处理大量的奥运会数据,并从中提取有价值的信息。同时,Spark还提供了丰富的数据处理和机器学习库,可以帮助我们进行数据挖掘和建模,以便更好地理解和预测奥运会的趋势和结果。通过结合Spark和AI技术,我们可以实现更深入的奥运会数据分析,并为奥运会的组织者、运动员和观众提供更好的决策支持和用户体验。 #### 引用[.reference_title] - *1* *2* [免费参加全球最大的Spark+AI峰会(Databricks 2020年6月22-26日)!免费访问峰会主题演讲及分组会议!](https://blog.csdn.net/duan_zhihua/article/details/106729096)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [热烈祝贺王家林大咖大数据经典传奇著作《Spark大数据商业实战三部曲》 畅销书籍第版 清华大学出版社发行...](https://blog.csdn.net/duan_zhihua/article/details/106294896)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BigCabbageFy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值