spark(RDD之间的基本转换)

来源:互联网 发布:北京java周末班 编辑:程序博客网 时间:2024/05/19 12:29

RDD,全称为弹性分布式数据集,是一个只读的分区记录集合。

创建RDD的方式有两种:
     1. 从稳定存储中的数据输入创建(即从Hadoop文件系统或与Hadoop兼容的其他持久化存储系统输入创建)。
     2. 其他的RDDs Transformation得到。

RDD有两种操作算子:
     1. Transformation(变换):Transformation操作是lazy的,即从一个RDD转换生成另一个新的RDD并不是马上执行,当等到Actions操作时,才会触发运算。
     2. Actions(行动):加在运算,触发spark提交作业(Job),将结果返回给程序或者写入的其他的存储系统。

本文主要关于RDD中一些算子的操作(以下程序都是在pyspark环境下运行的):
Transformation算子

  • map(func):将旧RDD中每个数据项通过用户自定义的函数转换成一个新的RDD
>>>data = [1,2,3,4,5,6,7,8,9,10]>>>rdd = sc.parallelize(data,3)>>>map = rdd.map(lamdba x:x*2)>>>def f(x):...     print x...>>map.foreach(f)

这里写图片描述

  • flatMap(func):将原来RDD中的每个元素通过自定义的函数转换为新的元素,并将生成的RDD的每个集合中的元素合并为一个集合。
>>>rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10],4)>>>map = rdd.flatMap(lambda x:range(1,x)).collect()>>>sort(map)

     使用flatMap的结果,合并为一个集合

这里写图片描述

     使用map的结果,包含几个集合

这里写图片描述

  • mapPartitions(func):将RDD的每个分区通过自定义的函数转换产生新的RDD。
>>> rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10],3)>>> def f(iterator): yield sum(iterator)... >>> rdd.mapPartitions(f).collect()

这里写图片描述

  • union(func):将两个RDD元素的数据类型相同的RDD进行合并操作,不去除重复,保存所有的元素。进行union操作后,RDD分区为原来两个总和。
>>>rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10],4)>>>rdd2 = sc.parallelize([1,2,3,4,5,6,7,8,9,10],3)>>>rdd.union(rdd2).collect()

     rdd的分区(通过len(rdd.glom().collect())查看:

这里写图片描述

     rdd2的分区:

这里写图片描述

     合并后的总分区及结果:

这里写图片描述
这里写图片描述

  • groupBy(func):返回元素的分组,将元素通过函数生成相应的key,之后将key相同的元素分为一组。
>>> rdd = sc.parallelize([1, 1, 2, 3, 5, 8])>>> result = rdd.groupBy(lambda x: x % 2).collect()>>> sorted([(x, sorted(y)) for (x, y) in result])结果:[(0, [2, 8]), (1, [1, 1, 3, 5])]
  • mapValue(func):对于(key,value)型数据中的value进行map操作
  • combineByKey(func):将RDD中元素按照自定义的方式进行合并
>>> x = sc.parallelize([("a", 1), ("b", 1), ("a", 1)])>>> def add(a, b): return a + str(b)>>> sorted(x.combineByKey(str, add, add).collect())结果:[('a', '11'), ('b', '1')]>>> def add(a, b): return a + b>>> sorted(x.combineByKey(int, add, add).collect())结果:[('a', 2), ('b', 1)]
  • reduceByKey(func):相对于combineByKey是更简单的一种情况,只是将两个value值合并成一个值。
>>> from operator import add>>> rdd = sc.parallelize([("a", 1), ("b", 1), ("a", 1)])>>> sorted(rdd.reduceByKey(add).collect())结果:[('a', 2), ('b', 1)]
  • partitionBy(func):对RDD进行分区操作,如果原有RDD的分区器和现在的分区器一致,则不重分,重分区后,每个分区之间不存在交集。
>>> pairs = sc.parallelize([1, 2, 3, 4, 2, 4, 1]).map(lambda x: (x, x))>>> sets = pairs.partitionBy(3).glom().collect()>>> print sets结果:[[(3, 3)], [(1, 1), (4, 4), (4, 4), (1, 1)], [(2, 2), (2, 2)]]

Action算子:通过SparkContext执行提交作业的runjob操作,出发RDDDAG(有向无环图)的执行

  • saveAsTextFile(path):将该RDD作为文本文件存储到指定HDFS目录,使用元素的字符串形式表示。
  • collectAsMap():对(key,value)型的RDD数据返回一个单机HashMap,对于重复的K的RDD元素,后面的元素会将前面的覆盖掉。
>>> m = sc.parallelize([(1, 2), (3, 4), (1, 5)]).collectAsMap()>>> m[1]5>>> m[3]4
  • top(num, key=None):返回最大的num个元素(“4”>”12”)。
>>> sc.parallelize([10, 4, 2, 12, 3]).top(3, key=str)[4, 3, 2]>>> sc.parallelize([10, 4, 2, 12, 3]).top(3, key=int)[12, 10, 4]
  • reduce(func):先对两个元素(key,value)进行reduce函数操作,然后将结果和迭代器取出来的下一个元素(key,value)进行reduce操作,直到迭代器遍历完所有元素,得到最后结果。
>>> sc.parallelize([1, 2, 3, 4, 5]).reduce(add)15
0 0
原创粉丝点击