Spark RDD基础(二)之常见的转化操作和行动操作及持久化

来源:互联网 发布:沙钢收购大数据 编辑:程序博客网 时间:2024/06/17 14:04

1.基本RDD操作

1.1元素转化操作

map()
map接受一个函数,把这个函数用于RDD的每个元素,将函数的返回结果作为结果RDD中对应元素的值,map的返回值类型不需要和输入类型一样

#计算RDD中各值的平方nums=sc.parallelize([1,2,3,4])squared=nums.map(lambda x:x*x).collect()for num in squared:    print "%i " % (num)

filter()
转化接受一个函数,将RDD中满足该函数的元素放入新RDD中返回

flatMap()
有时我们需要将每个输入元素生成多个输出元素,比如WordCount中将字符串切分为单词,实现该功能的操作叫做flatMap(),flatMap()返回的是一个返回值序列的迭代器。输出RDD是一个包含各个迭代器可访问的所有元素RDD

lines = sc.parallelize(["hello world", "hi"])words = lines.flatMap(lambda line: line.split(" "))words.first() # 返回"hello"

下图说明了map和flatMap的区别,flatMapRDD中是一个个迭代器中的具体元素,但是map中是一个个迭代器## 标题 ##
这里写图片描述

1.2伪集合操作

RDD不是严格意义上的集合,但是它支持许多集合操作比如:合并和相交

#生成一个只包含不同元素的RDD,注意distinct() 操作的开销很大distinct()#返回一个包含两个RDD中所有元素的RDD,此操作结果可能会有重复元素union(other)#与union功能类似,但是它会去重,但是性能也低很多intersection(other)#返回一个由只存在于第一个RDD中而不存在于第二个RDD 中的所有元素组成的RDDsubtract(other)#返回一个笛卡尔积,开销巨大cartesian(other)#对RDD进行采样sample(withReplacement, fraction, [seed])

distinct,union,intersection,subtract要求操作的RDD是相同数据类型

1.2行动操作

reduce
使用reduce(),可以很方便地计算出RDD中所有元素的总和、元素的个数,以及其他类型的聚合操作

sum = rdd.reduce(lambda x, y: x + y)

fold()
fold()与reduce()类似,接收与reduce接收的函数签名相同的函数,另外再加上一个初始值作为第一次调用的结果。(例如,加法初始值应为0,乘法初始值应为1)

num.fold(0,lambda x,y:x+y)

注意:fold() 和reduce() 都要求函数的返回值类型需要和我们所操作的RDD 中的元素类型相同,有时候我们需要返回一个不同类型的值,比如求平均值或者总和,我们可以这样操作先对数据使用map() 操作,来把元素转为该元素和1 的二元组,也就是我们所希望的返回类型。这样reduce() 就可以以二元组的形式进行归约了

aggregate()
aggregate()不要求返回值类型与RDD类型相同,使用aggregate() 时,需要提供我们期待返回的类型的初始值。然后通过一个函数把RDD 中的元素合并起来放入累加器。考虑到每个节点是在本地进行累加的,最终,还需要提供第二个函数来将累加器两两合并。

nums=sc.parallelize([1,2,3,4])sumCount = nums.aggregate((0, 0),    (lambda acc, value: (acc[0] + value, acc[1] + 1),    (lambda acc1, acc2: (acc1[0] + acc2[0], acc1[1] + acc2[1]))))return sumCount[0] / float(sumCount[1])

top()
使用top从RDD中获取前几个元素
top() 会使用数据的默认顺序,但我们也可以提供自己的比较函数,来提取前几个元素。

takeSample(withReplacement, num,seed)
让我们从数据中获取一个采样,并指定是否替换

countByValue()
各元素在RDD 中出现的次数

takeOrdered(num)
从RDD 中按照提供的顺序返回最前面的num 个元素

foreach(func)
对RDD 中的每个元素使用给定的函数,foreach与map类似,但是foreach无返回值(准确说返回void),map返回集合对象

2.持久化

Spark RDD 是惰性求值的,而有时我们希望能多次使用同一个RDD。如果简单
地对RDD 调用行动操作,Spark 每次都会重算RDD 以及它的所有依赖。这在迭代算法中消耗格外大。
为了避免多次计算同一个RDD,可以让Spark 对数据进行持久化。
出于不同的目的,我们可以为RDD 选择不同的持久化级别,持久化级别如下表
这里写图片描述

我们在第一次对这个RDD 调用行动操作前就调用了persist() 方法。persist() 调
用本身不会触发强制求值

RDD 还有一个方法叫作unpersist(),调用该方法可以手动把持久化的RDD 从缓
存中移除

spark快速大数据分析学习笔记

原创粉丝点击