七、RDD的重要函数

一、基本函数

  • map 函数:
  • map(f:T=>U) : RDD[T]=>RDD[U],表示将 RDD 经由某一函数 f 后,转变为另一个RDD。
  • flatMap 函数:
  • flatMap(f:T=>Seq[U]) : RDD[T]=>RDD[U]),表示将 RDD 经由某一函数 f 后,转变为一个新的 RDD,但是与 map 不同,RDD 中的每一个元素会被映射成新的 0 到多个元素(f 函数返回的是一个序列 Seq)。
  • filter 函数:
  • filter(f:T=>Bool) : RDD[T]=>RDD[T],表示将 RDD 经由某一函数 f 后,只保留 f 返回为 true 的数据,组成新的 RDD。
  • foreach 函数:
  • foreach(func),将函数 func 应用在数据集的每一个元素上,通常用于更新一个累加器,或者和外部存储系统进行交互,例如 Redis。
  • saveAsTextFile 函数:
  • saveAsTextFile(path:String),数据集内部的元素会调用其 toString 方法,转换为字符串形式,然后根据传入的路径保存成文本文件,既可以是本地文件系统,也可以是HDFS 等。

二、分区操作函数

每个RDD由多分区组成的,实际开发建议对每个分区数据的进行操作,map函数使用mapPartitions代替、foreache函数使用foreachPartition代替。

def f(iterator):
    for x in iterator:
        print(x)
sc.parallelize([1,2,3,4,5]).foreachPartition(f)
rdd = sc.parallelize([1,2,3,4],2)
def f(iterator):
    yield sum(iterator)
print(rdd.mapPartitions(f).collect())

三、重分区函数

对RDD中分区数目进行调整(增加分区或减少分区)

  • 增加分区函数
  • 函数名称:repartition,此函数使用的谨慎,会产生Shuffle。
>>> rdd = sc.parallelize([1,2,3,4,5,6,7], 4)
>>> sorted(rdd.glom().collect())
[[1], [2, 3], [4, 5], [6, 7]]
>>> len(rdd.repartition(2).glom().collect())
2
>>> len(rdd.repartition(10).glom().collect())
10
>>> rdd.glom().collect()
[[1], [2, 3], [4, 5], [6, 7]]
  • 减少分区函数
  • 函数名称:coalesce,此函数不会产生Shuffle,当且仅当降低RDD分区数目。
>>> sc.parallelize([1, 2, 3, 4, 5], 3).glom().collect()      
[[1], [2, 3], [4, 5]]
>>> sc.parallelize([1, 2, 3, 4, 5], 3).coalesce(1).glom().collect()
[[1, 2, 3, 4, 5]]
>>> sc.parallelize([1, 2, 3, 4, 5], 3).coalesce(4).glom().collect()
[[1], [2, 3], [4, 5]]
>>> sc.parallelize([1, 2, 3, 4, 5], 3).coalesce(4,True).glom().collect() 
[[4, 5], [2, 3], [], [1]]
  • 调整分区函数
  • 在PairRDDFunctions(此类专门针对RDD中数据类型为KeyValue对提供函数)工具类中partitionBy函数:
>>> pairs = sc.parallelize([1, 2, 3, 4, 2, 4, 1]).map(lambda x: (x, x)) 
>>> pairs.getNumPartitions()
2
>>> pairs.partitionBy(3).glom().collect()                
[[(3, 3)], [(1, 1), (4, 4), (4, 4), (1, 1)], [(2, 2), (2, 2)]]
>>> len(pairs.partitionBy(3).glom().collect())             
3

四、聚合函数

  • 集合中的聚合函数
from functools import reduce

def add(x,y):
    return x + y

sum1 = reduce(add,[1,2,3,4,5])
sum2 = reduce(lambda x,y:x+y, [1,2,3,4,5])
print(sum1)
print(sum2)
  • RDD中聚合函数
>>> from operator import add
>>> sc.parallelize([1,2,3,4,5]).reduce(add)
15
>>> sc.parallelize((2 for _ in range(10))).map(lambda x:1).cache().reduce(add)
10
>>> from operator import add
>>> sc.parallelize([1,2,3,4,5]).fold(0,add)
15
>>> sc.parallelize([1,2,3,4,5]).fold(10,add)
45
  • PairRDDFunctions聚合函数
>>> rdd = sc.parallelize([("a", 1), ("b", 1), ("a", 1)])
>>> sorted(rdd.groupByKey().mapValues(len).collect())
[('a', 2), ('b', 1)]
>>> sorted(rdd.groupByKey().mapValues(list).collect())
[('a', [1, 1]), ('b', [1])]
>>> sorted(rdd.reduceByKey(add).collect())
[('a', 2), ('b', 1)]
>>> sorted(rdd.foldByKey(0, add).collect())
[('a', 2), ('b', 1)]
>>> rdd.aggregateByKey(0, add, add).collect()
[('b', 1), ('a', 2)]
>>> sorted(rdd.aggregateByKey(0, add, add).collect())
[('a', 2), ('b', 1)]

五、关联函数

>>> x = sc.parallelize([(1001, "zhangsan"), (1002, "lisi"), (1003, "wangwu"), (1004, "zhangliu")])
>>> y = sc.parallelize([(1001, "sales"), (1002, "tech")])
>>> x.join(y).collect()
[(1001, ('zhangsan', 'sales')), (1002, ('lisi', 'tech'))]
>>> x.leftOuterJoin(y).collect()
[(1004, ('zhangliu', None)), (1001, ('zhangsan', 'sales')), (1002, ('lisi', 'tech')), (1003, ('wangwu', None))]
>>> x.rightOuterJoin(y).collect()
[(1001, ('zhangsan', 'sales')), (1002, ('lisi', 'tech'))]