5.1 rdd.map
map(f, preservesPartitioning=False)
作用:返回一个新的RDD,该RDD由每一个输入元素经过func函数转换后组成
>>> rdd = sc.parallelize(["b", "a", "c"])
>>> sorted(rdd.map(lambda x: (x, 1)).collect())
[('a', 1), ('b', 1), ('c', 1)]
5.2 rdd.mapPartitions
mapPartitions(f, preservesPartitioning=False)
作用:类似于map,但独立地每一个分片上运行,因此在类型为T的RDD上运行时,func的函数类型必须是(Int, Interator[T]) => Iterator[U]),假设有N个元素,有M个分区,那么map的函数将被调用N次,而mapPartitions被调用M次,一个函数一次处理所有分区
>>> rdd = sc.parallelize([1, 2, 3, 4], 2)
>>> def f(iterator):
yield sum(iterator)
>>> rdd.mapPartitions(f).collect()
[3, 7]
map()和mapPartition()区别:
①map()每次处理一条数据;
②mapPartition()每次处理一个分区的数据,这个分区的数据处理完后,原RDD中分区的数据才能释放,可能导致OOM(内存溢出);
③开发指导:当内存空间较大的时候建议使用mapPartition(),以提高处理效率
5.3 rdd.mapPartitionsWithIndex
作用:类似于mapPartitions,但func带有一个整数参数表示分片的索引值,因此在类型为T的RDD上运行,func的函数类型必须是(Int, Interator[T]) => Iterator[U])
>>> rdd = sc.parallelize([1, 2, 3, 4], 4)
>>> def f(splitIndex, iterator):
yield splitIndex
>>> rdd.mapPartitionsWithSplit(f).sum()
6
5.4 rdd.flatMap
rdd.flatMap(func)
作用:类似于map,每一个元素被映射成0或多个输出元素(所以func返回的是一个序列,而非单一元素)
>>> x = sc.parallelize([("a", ["x", "y", "z"]), ("b", ["p", "r"])])
>>> def f(x):
return x
>>> x.flatMapValues(f).collect()
[('a', 'x'), ('a', 'y'), ('a', 'z'), ('b', 'p'), ('b', 'r')]
5.5 rdd.glom
作用:将每一个分区形成一个数组,形成新的RDD类型
>>> rdd = sc.parallelize([1, 2, 3, 4], 2)
>>> sorted(rdd.glom().collect())
[[1, 2], [3, 4]]
5.6 rdd.groupBy
groupBy(f, numPartitions=None,partitionFunc=<function portable_hash>)
作用:分组,按照传入函数的返回值进行分组。将相同的key对应的值放入一个迭代器,分组后的数据形成了对偶元组(K, V),K表示分组的key,V表示分组的数据集合
>>> 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])]
5.7 rdd.filter
作用:过滤。返回一个新的RDD,该RDD由经过func函数计算后返回值为true的输入元素组成
>>> rdd = sc.parallelize([1, 2, 3, 4, 5])
>>> rdd.filter(lambda x: x % 2 == 0).collect()
[2, 4]
5.8 rdd.sample
sample(withReplacement, fraction, seed=None)
作用:以指定的随机种子随机抽样出数量为fraction的数据,withReplacement表示抽出的数据是否放回,true为有放回的抽样,false为无放回的抽样,seed用于指定随机数生成器种子
>>> rdd = sc.parallelize(range(100), 4)
>>> 6 <= rdd.sample(False, 0.1, 81).count() <= 14
True
5.9 rdd.distinct
distinct(numPartitions=None)
作用:对源RDD进行去重后返回一个新的RDD。默认情况下,只有8个并行任务来操作,但是可以传入一个可选numTasks参数改变它,存在数据shuffle过程(将RDD中一个分区的数据打乱重组到其他不同分区的操作)
>>> sorted(sc.parallelize([1, 1, 2, 3]).distinct().collect())
[1, 2, 3]
5.10 rdd.coalesce
coalesce(numPartitions, shuffle=False)
作用:缩减分区数,用于大数据集过滤后,提高小数据集的执行效率
>>> 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]]
查看RDD分区数
rdd.getNumPartitions() 1
5.11 rdd.repartition
repartition(numPartitions)
coalesce 与 repartition区别:
coalesce可以选择shuffle, repartition是对coalesce的封装, 然而调用coalesce时, shuffle = True
>>> 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
5.12 rdd.sortBy
sortBy(keyfunc, ascending=True, numPartitions=None)
sortBy(keyfunc):按照keyfunc数据的比较结果来排序,默认为正序,若要进行降序排列则可设为False,也可以对字典来进行排序
>>> tmp = [('a', 1), ('b', 2), ('1', 3), ('d', 4), ('2', 5)]
>>> sc.parallelize(tmp).sortBy(lambda x: x[0]).collect()
[('1', 3), ('2', 5), ('a', 1), ('b', 2), ('d', 4)]
>>> sc.parallelize(tmp).sortBy(lambda x: x[1]).collect()
[('a', 1), ('b', 2), ('1', 3), ('d', 4), ('2', 5)]