老汤大数据高薪就业课程链接:https://edu.51cto.com/sd/19ff1
课程咨询以及领取大额优惠请加微信:bigdatatang01
本文详细介绍RDD python api的action操作。
先创建一个RDD:
conf = SparkConf().setAppName("appName").setMaster("local") sc = SparkContext(conf=conf) parallelize_rdd = sc.parallelize([1, 2, 4, 3, 3, 6, 12], 2)
一、collect、take
""" 结果:[[1, 2, 4], [3, 3, 6]]。收集RDD的所有元素 """ print "parallelize_rdd = {0}".format(parallelize_rdd.glom().collect()) """ 结果:[1, 2] 获取RDD的第一个分区的前两个元素 """ print "take(2) = {0}".format(parallelize_rdd.take(2))
二、top
""" 结果:[12, 6] 获取RDD的最大的两个元素 """ print "top2 = {0}".format(parallelize_rdd.top(2)) """ 结果:[6, 4] 将RDD的元素转化成字符串,然后按照字符串的比较规则取最大的两个元素 """ print "top(2, key=str) = {0}".format(parallelize_rdd.top(2, key=str))
接下来,详细讲解top的第二个参数:
""" top的第二个参数是一个函数,一般是lambda表达式,可以看下面python内置的max的例子 当设置了这个key参数的时候,表示将数组中的元素应用这个key函数,按照返回的值来进行排序或者取最大值 """ d1 = {'name': 'egon', 'price': 100} d2 = {'name': 'rdw', 'price': 666} d3 = {'name': 'zat', 'price': 1} l1 = [d1, d2, d3] """ 表示取数组 l1 中name最大的那个元素的值 """ a = max(l1, key=lambda x: x['name']) """ 结果是:{'price': 1, 'name': 'zat'} """ print(a) """ 表示取数组 l1 中price最大的那个元素的值 """ b = max(l1, key=lambda x: x['price']) """ 结果是:{'price': 666, 'name': 'rdw'} """ print(b)
三、first、min、max、takeOrdered
""" 结果:first = 1 """ print "first = {0}".format(parallelize_rdd.first()) """ 结果:min = 1. 这个参数和上面top的第二个参数是一个含义 """ print "min = {0}".format(parallelize_rdd.min(key=lambda x: str(x))) """ 结果:max = 12 """ print "max = {0}".format(parallelize_rdd.max()) """ 结果:takeOrdered = [1, 12] 第二个参数和上面top的第二个参数是同一个含义 """ print "takeOrdered = {0}".format(parallelize_rdd.takeOrdered(2, key=str))
四、foreach、foreachPartition
def get_init_number(source): print "get init number from {0}, may be take much time........".format(source) time.sleep(1) return 1 def foreach_fun(x): init_number = get_init_number("foreach") print x + init_number + "===========" parallelize_rdd.foreach(foreach_fun) def foreach_partition_fun(values): """ 和foreach api的功能是一样,只不过一个是将函数应用到每一条记录,这个是将函数应用到每一个partition 如果有一个比较耗时的操作,只需要每一分区执行一次这个操作就行,则用这个函数 这个耗时的操作可以是连接数据库等操作,不需要计算每一条时候去连接数据库,一个分区只需连接一次就行 :param values: :return: """ init_number = get_init_number("foreach") for item in values: print item + init_number + "===========" parallelize_rdd.foreachPartition(foreach_partition_fun)
五、reduce、treeReduce
reduce_result = parallelize_rdd.reduce(lambda a, b: a + b) print "reduce_result = {0}".format(reduce_result) # reduce_result = 31 tree_reduce_result = parallelize_rdd.treeReduce(lambda a, b: a + b, 2) print "tree_reduce_result = {0}".format(tree_reduce_result) # tree_reduce_result = 31
六、fold
# 和reduce的功能类似,只不过是在计算每一个分区的时候需要加上初始值1,最后再将每一个分区计算出来的值相加再加上这个初始值 fold_result = parallelize_rdd.fold(0, lambda a, b: a + b) print "fold_result = {0}".format(fold_result) # fold_result = 31
七、aggregate、treeAggregate
seqOp = (lambda x, y: (x[0] + y, x[1] + 1)) combOp = (lambda x, y: (x[0] + y[0], x[1] + y[1])) aggregate_result = parallelize_rdd.aggregate((0, 0), seqOp, combOp) print "aggregate_result = {0}".format(aggregate_result) # aggregate_result = (31, 7)
对于reduce、treeReduce、fold、aggregate、treeAggregate的原理可以参考http://7639240.blog.51cto.com/7629240/1966172 和 spark core RDD api原理详解