Spark的intersection

intersection顾名思义,他是指交叉的。当两个RDD进行intersection后,将保留两者共有的。因此对于RDD1.intersection(RDD2) 和RDD2.intersection(RDD1) 。应该是一致的。

比如对于,List1 = {1,2,3,4,5} 和 List1 = {3,4,5,6,7},对于包含这两个List的RDD来说,他们进行一次intersection应该得到result={3,4,5}

Spark的subtract

subtract则和intersection不同,他是找出两者之间不一致的内容。

比如对于,List1 = {1,2,3,4,5} 和 List1 = {3,4,5,6,7}他们进行一次subtract得到的结果是跟顺序有关的。

list1.subtract(list2)

结果应该为

1 2

而对于

list2.subtract(list1)

结果应该为

6 7

Spark的union

union最好理解,他是把两个RDD进行整合,但不考虑其中重复的情况。比如对于,List1 = {1,2,3,4,5} 和 List1 = {3,4,5,6,7}他们进行一次union得到的结果是跟顺序无关的。结果应该为

result = {1,2,3,4,5,3,4,5,6,7}

Spark的distinct

distinc 是将RDD中重复的内容剔除,注意,这个剔除的过程并不会把重复的元素都去掉,而是重复的元素只保留一份。这当然很好理解,比如result = {1,2,3,4,5,3,4,5,6,7},进行一次distinct,则得到{1,2,3,4,5,6,7}

一个综合的例子

考虑到intersection、subtract、union和distinct比较常用,且在一个案例中能够很好体现其特点。因此我们这次获取的数据集是两个课程,lesson1和lesson2。lesson1中有十位同学,每个同学都有着许多个能力的估值,该估值是一个Int类型数据。lesson2中也是如此。对于这两个数据集我将其分别放在lesson1中和lesson2中。数据集和下面的代码均可以在github上找到并下载。

数据集分析

对于lesson1,里面有很多同学,每个同学又有很多次能力估值。在Spark入门(六)--Spark的combineByKey、sortBykey中已经提到过给每个人的成绩求平均分,因此这里不做这个处理。

这两个数据集我们解决如下的问题:

  • 0、计算lesson1和lesson2中每个同学的能力总估值
  • 1、找出lesson1中所有的同学(不重复)
  • 2、找出lesson2中所有同学(不重复)
  • 3、找出选了两门课程的同学
  • 4、找出只在lesson1而不在lesson2中的同学
  • 5、找出只在lesson2而不在lesson1中的同学

数据的部分内容展示

对于第0个问题,因为用到的并非本节的内容,因此标注为0。要求每个课程中的每个同学能力的总估值,首先要对数据进行处理,按空格拆分。拆分后的数据应该是(姓名,分数)的元组集合,然后根据姓名对分数进行累加。

  • 第一个问题中找出lesson1中所有同学,只要得到了每个同学能力的总估值,去掉分数,即可知道lesson1中的所有同学。

  • 第二题同理。

  • 第三题要找出选了两门课的同学,则要对两门课所有的同学进行一次整合,然后剔除重复的数据,即先union再distinc

  • 第四题要找到lesson1中而不在lesson二中的同学,则只要对lesson1的同学和lesson2中的同学进行一次substract即可

  • 第五题同理

scala实现


import org.apache.spark.{SparkConf, SparkContext} object SparkIntersectionAndSubtract { def main(args: Array[String]): Unit = { val conf = new SparkConf().setMaster("local").setAppName("SparkIntersectionAndSubtract") val sc = new SparkContext(conf) //课程一中的数据
val lesson1Data = sc.textFile("./lesson1").map(line => (line.split(" ")(0),line.split(" ")(1).toInt)) //将课程一中每个人的分数相加
val lesson1Grade = lesson1Data.reduceByKey(_+_) val lesson1Student = lesson1Grade.map(x=>x._1) //课程二中的数据处理
val lesson2Data = sc.textFile("./lesson2").map(line => (line.split(" ")(0),line.split(" ")(1).toInt)) //将课程二中每个人的分数相加
val lesson2Grade = lesson2Data.reduceByKey((x,y)=>x+y) val lesson2Student = lesson2Grade.map(x=>x._1) //在课程一中的人且在课程二中的人的集合
println("Students On Lesson1 And On Lesson2")
lesson1Student.intersection(lesson2Student).foreach(println) //在课程二中的人且在课程一中的人的集合,与上面的结果一致
println("Students On Lesson1 And On Lesson2")
lesson2Student.intersection(lesson1Student).foreach(println) //在课程一中的人但不在课程二中的人的集合
println("Students Only In Lesson1")
val onlyInLesson1 = lesson1Student.subtract(lesson2Student)
onlyInLesson1.foreach(println) //在课程二中的人但不在课程二中的人的集合
println("Students Only In Lesson2")
val onlyInLesson2 = lesson2Student.subtract(lesson1Student)
onlyInLesson2.foreach(println) //只选了一门课的同学
println("Students Only Choose One Lesson")
lesson1Student.union(lesson2Student).foreach(println) //两门课所有学生(不重复)
println("All the students")
lesson1Student.union(lesson2Student).distinct().foreach(print) } }

java实现

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2; public class SparkIntersectionAndSubtractJava { public static void main(String[] args){ SparkConf conf = new SparkConf().setMaster("local").setAppName("SparkIntersectionAndSubtractJava"); JavaSparkContext sc = new JavaSparkContext(conf); //java7实现
intersectionAndSubtractJava(sc); //java8实现
intersectionAndSubtractJava8(sc);
} public static void intersectionAndSubtractJava(JavaSparkContext sc){ JavaRDD<String> lesson1Data = sc.textFile("./lesson1"); JavaRDD<String> lesson2Data = sc.textFile("./lesson2"); JavaPairRDD<String,Integer> lesson1InfoData = lesson1Data.mapToPair(new PairFunction<String, String, Integer>() {
@Override
public Tuple2<String, Integer> call(String s) throws Exception {
return new Tuple2<>(s.split(" ")[0],Integer.parseInt(s.split(" ")[1]));
}
}); JavaPairRDD<String,Integer> lesson2InfoData = lesson2Data.mapToPair(new PairFunction<String, String, Integer>() {
@Override
public Tuple2<String, Integer> call(String s) throws Exception {
return new Tuple2<>(s.split(" ")[0],Integer.parseInt(s.split(" ")[1]));
}
}); JavaPairRDD<String,Integer> lesson1Grades = lesson1InfoData.reduceByKey(new Function2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) throws Exception {
return integer+integer2;
}
}); JavaPairRDD<String,Integer> lesson2Grades = lesson2InfoData.reduceByKey(new Function2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) throws Exception {
return integer+integer2;
}
}); JavaRDD<String> lesson1Students = lesson1Grades.map(new Function<Tuple2<String, Integer>, String>() {
@Override
public String call(Tuple2<String, Integer> stringIntegerTuple2) throws Exception {
return stringIntegerTuple2._1;
}
}); JavaRDD<String> lesson2Students = lesson2Grades.map(new Function<Tuple2<String, Integer>, String>() {
@Override
public String call(Tuple2<String, Integer> stringIntegerTuple2) throws Exception {
return stringIntegerTuple2._1;
}
}); //既在lesson1中又在lesson2中的学生
System.out.println("Students On Lesson1 And On Lesson2");
lesson1Students.intersection(lesson2Students).foreach(new VoidFunction<String>() {
@Override
public void call(String s) throws Exception {
System.out.println(s);
}
}); //既在lesson2中又在lesson1中的学生,与上面的结果一致
System.out.println("Students On Lesson1 And On Lesson2");
lesson2Students.intersection(lesson1Students).foreach(new VoidFunction<String>() {
@Override
public void call(String s) throws Exception {
System.out.println(s);
}
}); //只在lesson1中而不在lesson2中的学生
JavaRDD<String> studensOnlyInLesson1 = lesson1Students.subtract(lesson2Students);
System.out.println("Students Only In Lesson1");
lesson1Students.subtract(lesson2Students).foreach(new VoidFunction<String>() {
@Override
public void call(String s) throws Exception {
System.out.println(s);
}
}); //只在lesson2中而不在lesson1中的学生
JavaRDD<String> studensOnlyInLesson2 = lesson2Students.subtract(lesson1Students);
System.out.println("Students Only In Lesson2");
studensOnlyInLesson2.foreach(new VoidFunction<String>() {
@Override
public void call(String s) throws Exception {
System.out.println(s);
}
}); //只选了一门课的学生
JavaRDD<String> onlyOneLesson = studensOnlyInLesson1.union(studensOnlyInLesson2);
System.out.println("Students Only Choose One Lesson");
onlyOneLesson.foreach(new VoidFunction<String>() {
@Override
public void call(String s) throws Exception {
System.out.println(s);
}
}); System.out.println("All the students");
lesson1Students.union(lesson2Students).distinct().foreach(new VoidFunction<String>() {
@Override
public void call(String s) throws Exception {
System.out.println(s);
}
}); } public static void intersectionAndSubtractJava8(JavaSparkContext sc){ JavaRDD<String> lesson1Data = sc.textFile("./lesson1"); JavaRDD<String> lesson2Data = sc.textFile("./lesson2"); JavaPairRDD<String,Integer> lesson1InfoData =
lesson1Data.mapToPair(line -> new Tuple2<>(line.split(" ")[0],Integer.parseInt(line.split(" ")[1]))); JavaPairRDD<String,Integer> lesson2InfoData =
lesson2Data.mapToPair(line -> new Tuple2<>(line.split(" ")[0],Integer.parseInt(line.split(" ")[1]))); JavaPairRDD<String,Integer> lesson1Grades = lesson1InfoData.reduceByKey((x,y) -> x+y); JavaPairRDD<String,Integer> lesson2Grades = lesson2InfoData.reduceByKey((x,y) -> x+y); JavaRDD<String> studentsInLesson1 = lesson1Grades.map(x->x._1); JavaRDD<String> studentsInLesson2 = lesson2Grades.map(x->x._1); //既在lesson1中又在lesson2中的学生
studentsInLesson1.intersection(studentsInLesson2).foreach(name -> System.out.println(name)); //既在lesson2中又在lesson1中的学生,与上面的结果一致
studentsInLesson1.intersection(studentsInLesson2).foreach(name -> System.out.println(name)); //只在lesson1中的学生
JavaRDD<String> studentsOnlyInLesson1 = studentsInLesson1.subtract(studentsInLesson2);
studentsOnlyInLesson1.foreach(name -> System.out.println(name)); //只在lesson2中的学生
JavaRDD<String> studentsOnlyInLesson2 = studentsInLesson2.subtract(studentsInLesson1);
studentsOnlyInLesson2.foreach(name -> System.out.println(name)); //只选了一门课的学生
JavaRDD<String> studentsOnlyOneLesson = studentsOnlyInLesson1.union(studentsInLesson2);
studentsOnlyOneLesson.foreach(name -> System.out.println(name)); studentsInLesson1.union(studentsInLesson2).distinct().foreach(name -> System.out.println(name)); } }

python实现

from pyspark import SparkConf,SparkContext

conf = SparkConf().setMaster("local").setAppName("SparkCombineByKey")

sc = SparkContext(conf=conf)

#lesson1数据
lesson1Data = sc.textFile("./lesson1").map(lambda x:(x.split(" ")[0],int(x.split(" ")[1]))) #lesson2数据
lesson2Data = sc.textFile("./lesson2").map(lambda x:(x.split(" ")[0],int(x.split(" ")[1]))) #lesson1中每个人的总分
lesson1InfoData = lesson1Data.reduceByKey(lambda x,y:x+y) #lesson2中每个人的总分
lesson2InfoData = lesson2Data.reduceByKey(lambda x,y:x+y) #lesson1中的学生
studentsInLesson1 = lesson1InfoData.map(lambda x:x[0]) #lesson2中的学生
studentsInLesson2 = lesson2InfoData.map(lambda x:x[0]) #在lesson1中且在lesson2中的学生
print("Students On Lesson1 And On Lesson2")
studentsInLesson1.intersection(studentsInLesson2).foreach(print) #在lesson2中且在lesson1中的学生,与上面的结果一致
print("Students On Lesson1 And On Lesson2")
studentsInLesson2.intersection(studentsInLesson1).foreach(print) #只在lesson1中的学生
print("Students Only In Lesson1")
studensOnlyInLesson1 = studentsInLesson1.subtract(studentsInLesson2)
studensOnlyInLesson1.foreach(print) #只在lesson2中的学生
print("Students Only In Lesson2")
studensOnlyInLesson2 = studentsInLesson2.subtract(studentsInLesson1)
studensOnlyInLesson2.foreach(print) #只选了一门课的学生
print("Students Only Choose One Lesson")
studensOnlyInLesson1.union(studensOnlyInLesson2).foreach(print) #两门课所有学生(不重复)
print("All the students")
studentsInLesson1.union(studentsInLesson2).distinct().foreach(print)

运行得到结果

Students On Lesson1 And On Lesson2
Vicky
Amy
Lili
Bob
Coco Students On Lesson1 And On Lesson2
Vicky
Amy
Lili
Coco
Bob Students Only In Lesson1
Bill
David
Mike
Nancy
Lucy Students Only In Lesson2
White
Jimmy
Jason
John
Frank Students Only Choose One Lesson
Bill
David
Mike
Nancy
Lucy
White
Jimmy
Jason
John
Frank All the students
Vicky
Bill
Amy
White
Jimmy
Jason
Lili
David
Bob
Mike
Coco
Nancy
Lucy
John
Frank

通过上面的例子,非常具体地应用了intersection、subtract、union和distinct来解决具体的问题。并且利用好这几个方法能够很快速地进行一些数据集之间的关系操作。事实上,直接利用这几种方法比我们自己动手实现要好很多,因为spark中对这几种方法进行了优化。

数据集和代码均可以在github上找到并下载

转自:https://juejin.im/post/5c7b92276fb9a049bb7d0d10

Spark入门(七)--Spark的intersection、subtract、union和distinc的更多相关文章

  1. 一、spark入门之spark shell:wordcount

    1.安装完spark,进入spark中bin目录: bin/spark-shell   scala> val textFile = sc.textFile("/Users/admin/ ...

  2. 二、spark入门之spark shell:文本中发现5个最常用的word

    scala> val textFile = sc.textFile("/Users/admin/spark-1.5.1-bin-hadoop2.4/README.md") s ...

  3. Spark入门:Spark运行架构(Python版)

    此文为个人学习笔记如需系统学习请访问http://dblab.xmu.edu.cn/blog/1709-2/ 基本概念 *  RDD:是弹性分布式数据集(Resilient Distributed ...

  4. Spark 学习笔记之 union/intersection/subtract

    union/intersection/subtract: import org.apache.spark.SparkContext import org.apache.spark.rdd.RDD im ...

  5. spark 入门学习 核心api

    spark入门教程(3)--Spark 核心API开发 原创 2016年04月13日 20:52:28 标签: spark / 分布式 / 大数据 / 教程 / 应用 4999 本教程源于2016年3 ...

  6. Spark入门实战系列--3.Spark编程模型(上)--编程模型及SparkShell实战

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Spark编程模型 1.1 术语定义 l应用程序(Application): 基于Spar ...

  7. 【核心API开发】Spark入门教程[3]

    本教程源于2016年3月出版书籍<Spark原理.机制及应用> ,在此以知识共享为初衷公开部分内容,如有兴趣,请支持正版书籍. Spark综合了前人分布式数据处理架构和语言的优缺点,使用简 ...

  8. Spark 入门

    Spark 入门 目录 一. 1. 2. 3. 二. 三. 1. 2. 3. (1) (2) (3) 4. 5. 四. 1. 2. 3. 4. 5. 五.         Spark Shell使用 ...

  9. spark学习笔记总结-spark入门资料精化

    Spark学习笔记 Spark简介 spark 可以很容易和yarn结合,直接调用HDFS.Hbase上面的数据,和hadoop结合.配置很容易. spark发展迅猛,框架比hadoop更加灵活实用. ...

随机推荐

  1. Invalid action class configuration that references an unknown class问题原因之s:select

    早先做个练习项目就出现了这个错误,各种查资料,然后各种尝试,依然没有解决,不过可以确定是前台页面导致的. 今天又碰到了这个问题,头疼啊!不能再略过了,使用最笨的方法,一个模块一个模块的排除.先看下我的 ...

  2. 地址SQL文件

    文件下载 Beckoning

  3. windows下Jmeter压测端口占用问题

    https://blog.csdn.net/weixin_43757847/article/details/88188091 1 前情提要人脸识别项目中,云平台新增了人脸识别的校验接口.考虑到存在大量 ...

  4. 《内蒙古自治区第十二届大学生程序设计竞赛试题_G: 最大收益》

    问题 G: 最大收益 内存限制:128 MB时间限制:1 S标准输入输出 题目类型:传统评测方式:文本比较上传者:外部导入 提交:87通过:23 返回比赛提交提交记录 题目描述 Elly的叔叔经营一家 ...

  5. 常胜将军的深思变局:OPPO的渐变释放了怎样的行业信号?

    在经过了前几年的狂飙突进后,当下手机行业已经步入了自身的"十年之痒"阶段.利润贴地飞行.T型格局已定且竞争者实力愈强.创新不明显导致消费者换新驱动力降低.全球化竞争趋势凸显-- 也 ...

  6. Caused by: com.alibaba.fastjson.JSONException: syntax error, expect {, actual [, pos 0, fastjson-version 1.2

    环境: vue.js 问题: 当添加评论时 重新查询数据刷新数据控制台异常Caused by: com.alibaba.fastjson.JSONException: syntax error, ex ...

  7. 关于log4j中log4j.properties和log4j.xml的加载顺序

    如果采用log4j输出日志,要对log4j加载配置文件的过程有所了解. log4j启动时,默认会寻找source folder下的log4j.xml配置文件,若没有,会寻找log4j.properti ...

  8. nodejs日常总结

    1.node -v 查看当前node版本 2.npm root -g 查看npm安装路径(还有通过npm安装的vue-cli的路径) 默认: /usr/local/lib/node_modules r ...

  9. 使用Connector / Python连接MySQL/查询数据

    使用Connector / Python连接MySQL connect()构造函数创建到MySQL服务器的连接并返回一个 MySQLConnection对象 在python中有以下几种方法可以连接到M ...

  10. python js正则表达式

    一.定义正则表达式 /.../  用于定义正则表达式 /.../g 表示全局匹配 /.../i 表示不区分大小写 /.../m 表示多行匹配JS正则匹配时本身就是支持多行,此处多行匹配只是影响正则表达 ...