Spark自学之路(五)—— RDD常见的转化操作和行动操作

基本的RDD

1:针对各个元素的转化操作

最常用的map()和filter():map()函数接收一个函数,把这个函数用于RDD的每个元素,将函数的返回结果作为结果RDD中对应元素的值。filter()接收一个函数,并将RDD中满足该函数的元素放入新的RDD中返回。

计算RDD中各值的平方

from pyspark import SparkContext
sc = SparkContext( 'local[*]', 'test')
nums = sc.parallelize([1,2,3,4])
squared = nums.map(lambda x : x * x).collect()
for num in squared:
    print(num)

filter()

from pyspark import SparkContext
sc = SparkContext( 'local[*]', 'test')
nums = sc.parallelize([1,2,3,4])
squared = nums.filter(lambda x : x > 2).collect()
for num in squared:
    print(num)

#3
#4

flatMap():将函数应用到RDD中的每个元素,将返回的迭代器的所有内容构成新的RDD。通常用来切分单词

from pyspark import SparkContext
sc = SparkContext( 'local[*]', 'test')
words = sc.parallelize(["hello word","hi"])
word = words.flatMap(lambda line : line.split(" "))
word.foreach(print)

#hello
#word
#hi

flatMap()和Map()的区别:

Spark自学之路(五)—— RDD常见的转化操作和行动操作_第1张图片

2:伪集合操作

尽管RDD本身不是严格意义上的集合,但它也支持许多数学上的集合操作。

对数据分别为{1,2,3}和{3,4,5}的RDD进行针对两个RDD的转化操作

 

函数名 目的 示例 结果
union() 生成一个包含RDD中所有元素的RDD rdd.union(other) {1,2,3,4,5}
interection() 求两个RDD共同的元素RDD rdd.intersection(other) {3}
subtract() 移除一个RDD中内容 rdd.subtract(other) {1,2}
cartesian() 与另一个的笛卡儿积 rdd.cartesian(other) {(1,3),(1,4),...(3,5)} 

3:行动操作

对一个数据为{1,2,3,3}的RDD进行基本的RDD行动操作。

函数名

目的

示例

结果

collect()

返回RDD中的所有元素

Rdd.collect()

{1,2,3,3}

count()

RDD中的元素个数

Rdd.count()

4

take(num)

从RDD中返回num个元素

rdd.take(2)

{1,2}

top(num)

从RDD中返回最前面的num个元素

Rdd.top(2)

{3,3}

takeOrdered(num)(ordering)

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

Rdd.takeOrdered(2)(myOrdering)

{3,3}

reduce(func)

并行整合RDD中所有数据

Rdd.reduce(lambda x ,y : x+y)

9

fold(zero)(func)

和reduce一样,但是需要提供初始值

Rdd.fold(2)(lambda x,y :x+y)

9

aggregate(zeroValue)(seq0p,comb0p)

和reduce相似,但是通常返回不同类型的函数

Rdd.aggregate((0,0))

(9,4)

foreach(func)

对RDD中的每个元素使用给定的函数

Rdd.foreach(func)

持久化

SparkRDD时惰性求值的,而有时我们希望多次使用同一个RDD。如果简单地对RDD调用行动操作,Spark每次都会重算RDD以及它的所有依赖,这在迭代算法中常常会多次使用同一组数据,为了避免多次计算同一个RDD,可以让Spark对数据进行持久化。当我们让Spark持久化存储一个RDD时,计算出RDD的节点会分别保存他们所有求出的分区数据。如果一个有持久化数据的节点发生故障,Spark会在需要的时候用到缓存的数据时重新计算丢失的分区

from pyspark import SparkContext
sc = SparkContext( 'local[*]', 'test')
list = ["Hadoop","Spark","Hive"]
rdd = sc.parallelize(list)
rdd.cache()  #会调用persist(MEMORY_ONLY),但是,语句执行到这里,并不会缓存rdd,这是rdd还没有被计算生成
print(rdd.count()) #第一次行动操作,触发一次真正从头到尾的计算,这时才会执行上面的rdd.cache(),把这个rdd放到缓存中
print(','.join(rdd.collect())) #第二次行动操作,不需要触发从头到尾的计算,只需要重复使用上面缓存中的rdd

 持久化的级别

Spark自学之路(五)—— RDD常见的转化操作和行动操作_第2张图片

 

打印元素

在实际编程中,我们经常需要把RDD中的元素打印输出到屏幕上(标准输出stdout),一般会采用语句rdd.foreach(print)或者rdd.map(print)。当采用本地模式(local)在单机上执行时,这些语句会打印出一个RDD中的所有元素。但是,当采用集群模式执行时,在worker节点上执行打印语句是输出到worker节点的stdout中,而不是输出到任务控制节点Driver Program中,因此,任务控制节点Driver Program中的stdout是不会显示打印语句的这些输出内容的。为了能够把所有worker节点上的打印输出信息也显示到Driver Program中,可以使用collect()方法,比如,rdd.collect().foreach(print),但是,由于collect()方法会把各个worker节点上的所有RDD元素都抓取到Driver Program中,因此,这可能会导致内存溢出。因此,当你只需要打印RDD的部分元素时,可以采用语句rdd.take(100).foreach(print)。

你可能感兴趣的:(Spark)