pythonsparkpickle_Learning Spark (Python版) 学习笔记(一)----RDD 基本概念与命令
《Learning Spark》这本书算是Spark入门的必读书了,中文版是《Spark快速大数据分析》,不过豆瓣书评很有意思的是,英文原版评分7.4,评论都说入门而已深入不足,中文译版评分8.4,评论一片好评,有点意思。我倒觉得这本书可以作为官方文档的一个补充,刷完后基本上对Spark的一些基本概念、码简单的程序是没有问题的了。这本书有一个好处是它是用三门语言写的,Python/Java/Scala,所以适用性很广,我的观点是,先精通一门语言,再去学其他语言。由于我工作中比较常用的是Python,所以就用把Python相关的命令总结一下。下一阶段再深入学习Java和Scala。这一篇总结第一章-第三章的重点内容。
说到Spark,就不得不提到RDD,RDD,字面意思是弹性分布式数据集,其实就是分布式的元素集合。Python的基本内置的数据类型有整型、字符串、元祖、列表、字典,布尔类型等,而Spark的数据类型只有RDD这一种,在Spark里,对数据的所有操作,基本上就是围绕RDD来的,譬如创建、转换、求值等等。所有RDD的转换都是lazy(惰性求值)的,RDD的转换操作会生成新的RDD,新的RDD的数据依赖于原来的RDD的数据,每个RDD又包含多个分区。那么一段程序实际上就构造了一个由相互依赖的多个RDD组成的有向无环图(DAG)。并通过在RDD上执行动作将这个有向无环图作为一个Job提交给Spark执行。理解RDD后可以避免以后走很多弯路。关于RDD的特点,可以搜到很多资料,其实我们只需要理解两点就可以了:
1.不可变
2.分布式
有人会觉得很奇怪,如果RDD不可变,那么在进行数据操作的时候,怎么改变它的值,怎么进行计算呢?其实RDD支持两种操作:
1.Tansformation(转化操作):返回值还是一个RDD
2.Action(行动操作):返回值不是一个RDD
第一种Transformation是返回一个新的RDD,如map(),filter()等。这种操作是lazy(惰性)的,即从一个RDD转换生成另一个RDD的操作不是马上执行,只是记录下来,只有等到有Action操作是才会真正启动计算,将生成的新RDD写到内存或hdfs里,不会对原有的RDD的值进行改变。而Action操作才会实际触发Spark计算,对RDD计算出一个结果,并把结果返回到内存或hdfs中,如count(),first()等。
通俗点理解的话,就是假设你写了一堆程序,里面对数据进行了多次转换,这个时候实际上没有计算,就只是放着这里。在最后出结果的时候会用到Action操作,这个时候Action会执行与之相关的转换操作,运算速度会非常快(一是Action不一定需要调用所有的transformation操作,二是只有在最后一步才会计算相关的transformation操作)。如果Transformation没有lazy性质的话,每转换一次就要计算一次,最后Action操作的时候还要计算一次,会非常耗内存,也会极大降低计算速度。
还有一种情况,如果我们想多次使用同一个RDD,每次都对RDD进行Action操作的话,会极大的消耗Spark的内存,这种情况下,我们可以使用RDD.persist()把这个RDD缓存下来,在内存不足时,可以存储到磁盘(disk)里。在Python中,储存的对象永远是通过Pickle库序列化过的,所以社不设置序列化级别不会产生影响。
RDD的性质和操作方式讲完了,现在来说说怎么创建RDD,有两种方式
1.读取一个外部数据集
2.在内存中对一个集合进行并行化(parallelize)
第二种方式相对来说更简单,你可以直接在shell里快速创建RDD,举个例子:
1 A = [1,2,3,4,5]
2 lines = sc.parallelize(A)
3 #另一种方式
4 lines = sc.parallelize([1,2,3,4,5])
但是这种方式并不是很好,因为你需要把你的整个数据集放在内存里,如果数据量比较大,会很占内存。所以,可以在测试的时候用这种方式,简单快速。
读取外部数据及时需要用到SparkContext.textFile()
1lines = sc.textFile("README.md")
RDD的操作命令很多,包括map(),filter()等Transformation操作以及reduce(),fold(),aggregate()等Action操作。
常见的Transformation操作:
map( )和flatMap( )的联系和区别
map( ):接收一个函数,应用到RDD中的每个元素,然后为每一条输入返回一个对象。
filter( ):接收一个函数,将函数的元素放入新的RDD中返回。
flatMap( ):接收一个函数,应用到RDD中的每个元素,返回一个包含可迭代的类型(如list等)的RDD,可以理解为先Map(),后flat().
用一个图可以很清楚的理解:
伪集合操作:
1 distinct( )、union( )、intersection( )、subtract( )
2 distinct( ):去重
3 union( ):两个RDD的并集
4 intersection( ):两个RDD的交集
5 subtract( ):两个RDD的补集
6 cartesian( ):两个RDD的笛卡尔积(可以应用于计算相似度中,如计算各用户对各种产品的预期兴趣程度)
注:
1.intersection( )的性能比union( )差很多,因为它需要数据混洗来发现共同数据
2.substract( )也需要数据混洗
常见的Action操作:
1 reduce( ):接收一个函数作为参数,这个函数要操作两个相同元素类型的RDD,也返回一个同样类型的RDD,可以计算RDD中元素的和、个数、以及其他聚合类型的操作。
2
3 fold( ):和reduce一样,但需要提供初始值。
4
5 aggregate( ):和fold类似,但通常返回不同类型的函数。
6
7 注:
关于fold()和aggregate(),再说点题外话。fold()只能做同构聚合操作,就是说,如果你有一个RDD[X],通过fold,你只能构造出一个X。但是如果你想通过RDD[X]构造一个Y呢?那就得用到aggregate()了,使用aggregate时,需要提供初始值(初始值的类型与最终返回的类型相同),然后通过一个函数把一RDD的元素合并起来放到累加器里,再提供一个函数将累加器两两相加。由此可以看出,fold()需要保证灭个partition能够独立进行运算,而aggregate()对于不同partition(分区)提交的最终结果专门定义了一个函数来进行处理。
RDD还有很多其他的操作命令,譬如collect(),count(),take(),top(),countByValue(),foreach()等,限于篇幅,就不一一表述了。
最后来讲讲如何向Spark传递函数:
两种方式:
1.简单的函数:lambda表达式。
适合比较短的函数,不支持多语句函数和无返回值的语句。
2.def函数
会将整个对象传递过去,但是最好不要传递一个带字段引用的函数。如果你传递的对象是某个对象的成员,或者在某个函数中引用了一个整个字段,会报错。举个例子:
1 class MyClass(object):
2 def __init__(self):
3 self.field = “Hello”
4
5 def doStuff(self, rdd):
6 #报错:因为在self.field中引用了整个self
7 return rdd.map(lambda s: self.field + x)
解决方法:直接把你需要的字段拿出来放到一个局部变量里,然后传递这个局部变量就可以了。
1 class MyClass(object):
2 def __init__(self):
3 self.field = “Hello”
4
5 def doStuff(self, rdd):
6 #将需要的字段提取到局部变量中即可
7 field = self.field
8 return rdd.map(lambda s: field + x)
前面三章讲了Spark的基本概念和RDD的特性以及一些简单的命令,比较简单。后面三章主要讲了键值对操作、数据的读取和保存以及累加器、广播变量等,下周再更新。
原文转自:http://www.cnblogs.com/charlotte77/p/5412709.html
pythonsparkpickle_Learning Spark (Python版) 学习笔记(一)----RDD 基本概念与命令相关推荐
- 林子雨-Spark入门教程(Python版)-学习笔记(二)
第3章 Spark编程基础 从文件加载数据 从文件系统中加载数据创建RDD--textFile()方法,该方法把文件的URI作为参数 注意: (1)本地文件系统的路径,必须要保证在所有的worker节 ...
- 林子雨-Spark入门教程(Python版)-学习笔记(一)
第1章 Spark的设计与运行原理 简介 hadoop中计算框架MapReduce的缺点: 表能能力有限,计算都必须要转化成Map和Reduce两个操作,难以表示复杂场景 IO开销大,中间结果写入到磁 ...
- 1算法分析——数据结构与算法Python版学习笔记
什么是算法分析? 计算资源指标:一种是算法解决问题过程中需要的储存空间或内存,另一种是算法的执行时间 运行时间检测 time模块,获取计算机系统当前时间 例如: 方法一:累计求和程序的运行时间检测 i ...
- Opencv Python版学习笔记01.计算机眼中的图像
在计算机眼里,图像是通过数字矩阵的形式存储的.如上图所示,这张图片被分为了若干个小方格,但是每个方格仍然不够小,随意取出一个方格放大观察,这个方格是由许多小格组成的,其中每个小格叫做一个像素点,像素点 ...
- 36篇博文带你学完opencv :python+opencv进阶版学习笔记目录
基础版学习笔记传送门 36篇博文带你学完opencv :python3+opencv学习笔记汇总目录(基础版) 进阶版笔记 项目 opencv进阶学习笔记1: 调用摄像头用法大全(打开摄像头,打开摄像 ...
- 《Python编程:从入门到实战》(第2版)学习笔记 第5章 if语句
[写在前面]为进一步提高自己的python代码能力,打算把几本经典书籍重新过一遍,形成系统的知识体系,同时适当记录一些学习笔记,我尽量及时更新!先从经典的<Python编程:从入门到实战> ...
- 笨办法学python第五版_最新《笨办法学python》学习笔记
<笨办法学 python >学习笔记( Python 3.6 ) 习题 19 ex19.py # -*- coding: utf-8 -*- # 定义 cheese_and_cracker ...
- Python数据结构学习笔记——链表:无序链表和有序链表
目录 一.链表 二.无序链表 实现步骤分析 三.无序链表的Python实现代码 四.有序链表 实现步骤分析 五.有序链表的Python实现代码 结语 一.链表 链表中每一个元素都由为两部分构成:一是该 ...
- Python数据结构学习笔记——队列和双端队列
目录 一.队列的定义 二.队列 实现步骤分析 三.队列的Python实现代码 四.队列的应用 六人传土豆游戏 五.双端队列的定义 六.双端队列 实现步骤分析 七.双端队列的Python实现代码 八.双 ...
最新文章
- div块内的CSS中心文本(水平和垂直)
- ITK:图像重新取样
- dataguard如何实现切换_深度干货 | 如何借助云原生搞定Oracle备份快速恢复?
- Grand Central Dispatch(GCD)
- 曲线 神经网络_神经网络的数学基础-8(完结)
- 实现一个简单的HTTP
- css的position属性取值
- 编译OpenJDK8:OpenJDK8与OpenJDK8u运行结果相差很大
- 哔哩哔哩视频下载助手
- android 中通过SimpleDateFormat自定义显示英文的时间格式
- 基于Unity3d的FPS与塔防相结合的游戏设计
- 前复权 后复权和不复权是什么意思
- S3C2440 蜂鸣器 汇编语言,S3C2440的基础功能模块实现过程
- 零伽壹浅谈:区块链技术在审计工作的应用
- macbook录屏声音收录的处理
- FPGA基础设计(10)Verilog行为级建模(过程赋值)
- 镜子中的 Google
- WEB开发碰到的问题及经验十八则
- pythonturtle写字_python用turtle写字
- 修改Chromium源码实现HEVC/H.265 4K视频播放