spark 窗口函数row_number练习以及用spark core实现
来源:互联网 发布:javascript 实战 编辑:程序博客网 时间:2024/04/28 12:24
常用于对数据进行分组并取每个分组中的TopN数据。
示例数据如下:
class1 90
class2 56
class1 87
class1 76
class2 88
class1 95
class1 74
class2 87
class2 67
class2 77
1、直接使用Spark core中的api来实现分组取topN功能:
首先将数据源读入代JavaRDD中,然后解析每一行数据,将每一行的第一个元素作为key,第二元素作为value构成tuple的RDD
SparkConf conf = new SparkConf().setAppName("groupTopN").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> lines = sc.textFile("C:\\Temp\\groupTopN.txt");
JavaPairRDD<String,Integer> pairs = lines.mapToPair(new PairFunction<String, String, Integer>() {
@Override
public Tuple2<String, Integer> call(String line) throws Exception {
String[] lineSplited = line.split(" ");
return new Tuple2<String,Integer>(lineSplited[0],Integer.valueOf(lineSplited[1]));
}
});
得到pairs是一个二元组的RDD,直接调用groupByKey()函数,就可以按照key来进行分组了
JavaPairRDD<String, Iterable<Integer>> grouped = pairs.groupByKey();
1
分组后每个key对应的这一个value的集合,这里,需要对每个key对应的value集合首先进行排序,然后取其前N个元素即可
JavaPairRDD<String,Iterable> groupedTopN = grouped.mapToPair(new PairFunction<Tuple2<String,Iterable<Integer>>, String, Iterable>() {
@Override
public Tuple2<String, Iterable> call(Tuple2<String, Iterable<Integer>> values) throws Exception {
Iterator<Integer> iter = values._2.iterator();
List<Integer> list = new ArrayList<Integer>();
while(iter.hasNext()){
list.add(iter.next());
}
//将list中的元素排序
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer t1, Integer t2) {
int i1 = t1;
int i2 = t2;
return -(i1 - i2);//逆序排列
}
});
List<Integer> top3 = list.subList(0, 3);//直接去前3个元素
return new Tuple2<String,Iterable>(values._1,top3);
}
});
为了便于验证,直接在本地进行测试,并打印显示
groupedTopN.foreach(new VoidFunction<Tuple2<String,Iterable>>() {
@Override
public void call(Tuple2<String, Iterable> t) throws Exception {
System.out.println(t._1);
Iterator iterator = t._2.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("====华丽的分割线=======");
}
2、使用SparkSQL的窗口函数来时上同样的功能
思路:
窗口函数是HiveSQL中特有的,因此,首先将数据导入到hive表中,然后映射到Spark的DataFrame,在sql语句中直接调用窗口函数即可实现该功能
首先,直接在HiveSQL中创建对应的hive表,然后导入本地数据到hive表中
SparkConf conf = new SparkConf().setAppName("WindowFunctionTopN").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
HiveContext hiveContext = new HiveContext(sc.sc());
//将数据导入到hive表中
hiveContext.sql("DROP TABLE IF EXISTS class_info");
hiveContext.sql("CREATE TABLE IF NOT EXISTS class_info ("
+ "class STRING,"
+ "score INT");
hiveContext.sql("LOAD DATA "
+ "LOCAL INPATH '/cqt/testdata/groupTopN.txt' "
+ "INTO TABLE class_info");
然后,直接调用窗口函数row_number(),注意窗口函数的调用语法
DataFrame tom3DF = hiveContext.sql("select class,score from" +"(select class,score,"
+ "row_number() OVER (PARTITION BY class ORDER BY score DESC) rank from class_info) tmp where rank<=3");
将得到的数据回写到hive表中保存即可
// 将每组排名前3的数据,保存到一个表中
hiveContext.sql("DROP TABLE IF EXISTS grouped_top3");
tom3DF.saveAsTable("grouped_top3");
其他函数请参考 http://lxw1234.com/archives/tag/hive-window-functions
示例数据如下:
class1 90
class2 56
class1 87
class1 76
class2 88
class1 95
class1 74
class2 87
class2 67
class2 77
1、直接使用Spark core中的api来实现分组取topN功能:
首先将数据源读入代JavaRDD中,然后解析每一行数据,将每一行的第一个元素作为key,第二元素作为value构成tuple的RDD
SparkConf conf = new SparkConf().setAppName("groupTopN").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
JavaRDD<String> lines = sc.textFile("C:\\Temp\\groupTopN.txt");
JavaPairRDD<String,Integer> pairs = lines.mapToPair(new PairFunction<String, String, Integer>() {
@Override
public Tuple2<String, Integer> call(String line) throws Exception {
String[] lineSplited = line.split(" ");
return new Tuple2<String,Integer>(lineSplited[0],Integer.valueOf(lineSplited[1]));
}
});
得到pairs是一个二元组的RDD,直接调用groupByKey()函数,就可以按照key来进行分组了
JavaPairRDD<String, Iterable<Integer>> grouped = pairs.groupByKey();
1
分组后每个key对应的这一个value的集合,这里,需要对每个key对应的value集合首先进行排序,然后取其前N个元素即可
JavaPairRDD<String,Iterable> groupedTopN = grouped.mapToPair(new PairFunction<Tuple2<String,Iterable<Integer>>, String, Iterable>() {
@Override
public Tuple2<String, Iterable> call(Tuple2<String, Iterable<Integer>> values) throws Exception {
Iterator<Integer> iter = values._2.iterator();
List<Integer> list = new ArrayList<Integer>();
while(iter.hasNext()){
list.add(iter.next());
}
//将list中的元素排序
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer t1, Integer t2) {
int i1 = t1;
int i2 = t2;
return -(i1 - i2);//逆序排列
}
});
List<Integer> top3 = list.subList(0, 3);//直接去前3个元素
return new Tuple2<String,Iterable>(values._1,top3);
}
});
为了便于验证,直接在本地进行测试,并打印显示
groupedTopN.foreach(new VoidFunction<Tuple2<String,Iterable>>() {
@Override
public void call(Tuple2<String, Iterable> t) throws Exception {
System.out.println(t._1);
Iterator iterator = t._2.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("====华丽的分割线=======");
}
2、使用SparkSQL的窗口函数来时上同样的功能
思路:
窗口函数是HiveSQL中特有的,因此,首先将数据导入到hive表中,然后映射到Spark的DataFrame,在sql语句中直接调用窗口函数即可实现该功能
首先,直接在HiveSQL中创建对应的hive表,然后导入本地数据到hive表中
SparkConf conf = new SparkConf().setAppName("WindowFunctionTopN").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
HiveContext hiveContext = new HiveContext(sc.sc());
//将数据导入到hive表中
hiveContext.sql("DROP TABLE IF EXISTS class_info");
hiveContext.sql("CREATE TABLE IF NOT EXISTS class_info ("
+ "class STRING,"
+ "score INT");
hiveContext.sql("LOAD DATA "
+ "LOCAL INPATH '/cqt/testdata/groupTopN.txt' "
+ "INTO TABLE class_info");
然后,直接调用窗口函数row_number(),注意窗口函数的调用语法
DataFrame tom3DF = hiveContext.sql("select class,score from" +"(select class,score,"
+ "row_number() OVER (PARTITION BY class ORDER BY score DESC) rank from class_info) tmp where rank<=3");
将得到的数据回写到hive表中保存即可
// 将每组排名前3的数据,保存到一个表中
hiveContext.sql("DROP TABLE IF EXISTS grouped_top3");
tom3DF.saveAsTable("grouped_top3");
其他函数请参考 http://lxw1234.com/archives/tag/hive-window-functions
0 0
- spark 窗口函数row_number练习以及用spark core实现
- 使用Spark core和SparkSQL的窗口函数分别实现分组取topN的操作
- 使用Spark core和SparkSQL的窗口函数分别实现分组取topN的操作
- Spark分析窗口函数
- Spark分析窗口函数
- Spark-窗口函数
- [2.4]以row_number为例解读spark sql的窗口函数
- spark core 非实时计算滑动窗口
- Spark core
- Spark Core
- spark窗口函数报错
- Spark的DataFrame的窗口函数使用
- Spark-SQL-core
- Spark-Core源码阅读
- Spark Core 问题详解
- spark core 日志屏蔽
- spark core 2.0 SortShuffleManager
- spark core 2.0 OutputCommitCoordinator
- GCC 升级4.8 支持c++11
- IO多路复用之epoll
- 列表,元组里面常用的几种函数以及方法
- git 删除某个project的远程仓库及其下属所有分支
- 三极管放大电路
- spark 窗口函数row_number练习以及用spark core实现
- running vpxa start解决方法
- 浅谈前端JavaScript编程风格
- linux c tool系列------sendevent.c
- [leetcode]438. Find All Anagrams in a String
- 子frame获取外部元素
- Prism4文档翻译(第二章 全部内容)
- 【PAT】1084. Broken Keyboard
- 2016书单总结--写给大忙人看的JavaSE8-Stream