一.概述

  在许多数据中,都存在类别的数据,在一些功能中需要根据类别分别获取前几或后几的数据,用于数据可视化或异常数据预警。在这种情况下,实现分组TopN就显得非常重要了,因此,使用了Spark聚合函数和排序算法实现了分布式TopN计算功能。

  

二.代码实现

 package scala

 import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql.types.{StringType, StructField, StructType}
import org.apache.spark.sql.{Row, SparkSession} /**
* 计算分组topN
* Created by Administrator on 2019/11/20.
*/
object GroupTopN {
Logger.getLogger("org").setLevel(Level.WARN) // 设置日志级别
def main(args: Array[String]) {
//创建测试数据
val test_data = Array("CJ20191120,201911", "CJ20191120,201910", "CJ20191105,201910", "CJ20191105,201909", "CJ20191111,201910")
val spark = SparkSession.builder().appName("GroupTopN").master("local[2]").getOrCreate()
val sc = spark.sparkContext
val test_data_rdd = sc.parallelize(test_data).map(row => {
val Array(scene, cycle) = row.split(",")
Row(scene, cycle)
})
// 设置数据模式
val structType = StructType(Array(
StructField("scene", StringType, true),
StructField("cycle", StringType, true)
))
// 转换为df
val test_data_df = spark.createDataFrame(test_data_rdd, structType)
test_data_df.createOrReplaceTempView("test_data_df")
// 拼接周期
val scene_ws = spark.sql("select scene,concat_ws(',',collect_set(cycle)) as cycles from test_data_df group by scene")
scene_ws.count()
scene_ws.show()
scene_ws.createOrReplaceTempView("scene_ws")
/**
* 定义参数确定N的大小,暂定为1
*/
val sum = 1
// 创建广播变量,把N的大小广播出去
val broadcast = sc.broadcast(sum)
/**
* 定义Udf实现获取组内的前N个数据
*/
spark.udf.register("getTopN", (cycles : String) => {
val sum = broadcast.value
var mid = ""
if(cycles.contains(",")){ // 多值
val cycle = cycles.split(",").sorted.reverse // 降序排序
val min = Math.min(cycle.length, sum)
for(i <- 0 until min){
if(mid.equals("")){
mid = cycle(i)
}else{
mid += "," + cycle(i)
}
}
}else{ // 单值
mid = cycles
}
mid
}) val result = spark.sql("select scene,getTopN(cycles) cycles from scene_ws")
result.show()
spark.stop()
}
}

三.结果

  

  

四.备注

  当N大于1时,多个数据会拼接在一起,若想每个一行,可是使用使用列转行功能,参考我的博客:https://www.cnblogs.com/yszd/p/11266552.html

Spark实现分组TopN的更多相关文章

  1. 020 Spark中分组后的TopN,以及Spark的优化(重点)

    一:准备 1.源数据 2.上传数据 二:TopN程序编码 1.程序 package com.ibeifeng.bigdata.spark.core import java.util.concurren ...

  2. 大数据学习day29-----spark09-------1. 练习: 统计店铺按月份的销售额和累计到该月的总销售额(SQL, DSL,RDD) 2. 分组topN的实现(row_number(), rank(), dense_rank()方法的区别)3. spark自定义函数-UDF

    1. 练习 数据: (1)需求1:统计有过连续3天以上销售的店铺有哪些,并且计算出连续三天以上的销售额 第一步:将每天的金额求和(同一天可能会有多个订单) SELECT sid,dt,SUM(mone ...

  3. QL查询案例:取得分组 TOP-N

    [转]SQL查询案例:取得分组 TOP-N CREATE TABLE TopnTest ( name     VARCHAR(10),   --姓名 procDate DATETIME,       ...

  4. 用Spark完成复杂TopN计算的两种逻辑

    如果有商品品类的数据pairRDD(categoryId,clickCount_orderCount_payCount),用Spark完成Top5,你会怎么做? 这里假设使用Java语言进行编写,那么 ...

  5. 取分组TOPN好理解案例

  6. 分别使用Hadoop和Spark实现TopN(1)——唯一键

    0.简介 TopN算法是一个经典的算法,由于每个map都只是实现了本地的TopN算法,而假设map有M个,在归约的阶段只有M x N个,这个结果是可以接受的并不会造成性能瓶颈. 这个TopN算法在ma ...

  7. TopN问题(分别使用Hadoop和Spark实现)

    简介 TopN算法是一个经典的算法,由于每个map都只是实现了本地的TopN算法,而假设map有M个,在归约的阶段只有M x N个,这个结果是可以接受的并不会造成性能瓶颈. 这个TopN算法在map阶 ...

  8. spark面试总结3

    Spark core面试篇03 1.Spark使用parquet文件存储格式能带来哪些好处? 1) 如果说HDFS 是大数据时代分布式文件系统首选标准,那么parquet则是整个大数据时代文件存储格式 ...

  9. Spark面试相关

    Spark Core面试篇01 随着Spark技术在企业中应用越来越广泛,Spark成为大数据开发必须掌握的技能.前期分享了很多关于Spark的学习视频和文章,为了进一步巩固和掌握Spark,在原有s ...

随机推荐

  1. JDOJ 1789: 高精度A+B

    JDOJ 1789: 高精度A+B JDOJ传送门 洛谷 P1601 A+B Problem(高精) 洛谷传送门 Description 已知两个整数A.B 求A+B Input 第一行为A 第二行为 ...

  2. js正则表达式常用方法总结

    1.test()  方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false. var patt = /e/; patt.test("The ...

  3. AWS云教育账号创建以及搭建数据库

    注册过程繁琐,本文强调关键几点 首先拿到aws的二维码,进入之后填写相关个人信息,用学校邮箱注册,用学校邮箱注册!! 之后审核会有大约10分钟的过程,之后会收到确认邮件 点进去之后就可以设置自己的密码 ...

  4. 一些开源cdc框架以及工具

    以下是一些cdc工具,没有包含商业软件的 zendesk maxwell 参考地址 https://github.com/zendesk/maxwell 功能 mysql 2 json 的kafaa ...

  5. 【Step-By-Step】第 三 周

    本周面试题一览: 什么是XSS攻击,XSS 攻击可以分为哪几类?我们如何防范XSS攻击? 如何隐藏页面中的某个元素? 浏览器事件代理机制的原理是什么? setTimeout 倒计时为什么会出现误差? ...

  6. [LeetCode] 694. Number of Distinct Islands 不同岛屿的个数

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  7. 《30天自制操作系统》笔记2 --- 初步了解汇编产生的二进制(Day1)

    nask.exe应该就是nas kit(nas开发工具的意思),由于这个编译器是作者自己写的,所以这种汇编语言应该是作者改造出来的,所以我叫它nas汇编语言. 作者说nask是模仿nasm语法的,关于 ...

  8. linux重定向 null和zero

    文件描述符 linux下一切皆文件 文件描述符,是内核为了高效管理已经被打开的文件所创建的索引,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符; 文件描述符是一个简单的非负整数,用 ...

  9. 利用mysql的LOAD DATA INFILE的功能读取客户端文件

    前言:今天在浏览某知论坛时,看到某大佬在渗透过程中使用伪造的MySQL服务端读取客户端文件,此大佬在利用过程中描述得不是很详细,作为小白的我看不懂啊,由此产生了此篇文章. 某大佬文章:https:// ...

  10. Extra:Variable Types

    文章著作权归作者所有.转载请联系作者,并在文中注明出处,给出原文链接. 本系列原更新于作者的github博客,这里给出链接. 在我们使用Cg或者HLSL进行shader编写的过程中,常常涉及到一些变量 ...