spark学习笔记__chap4_spark基础原理__4.3_RDD Action及输出算子详解__进行中

  1. RDD是Spark里面最重要的基础抽象,代表的是弹性的分布式的数据集。RDD有很多的实现类,在各个RDD之上提供了transformation和action两大类算子。transformation算子具有惰性,他们并不会触发作业的提交,一个个的transformation算子操作只是定义出了计算所依赖的DAG有向无环图,它只是一个计算的逻辑,而真正会触发作业提交的算子是属于action类别的算子。这一节我们将讲到RDD上的大部分API!
    首先来看action类的算子

  2. spark中如何实现分布式并行的计算一个数据集中所有元素的和?这属于一个聚合操作,spark先把数据分区,每个分区由任务调度器分发到不同的节点分别计算和,计算的结果返回driver节点,在driver节点将所有节点的返回值相加,就得到了整个数据集的和了。spark里实现了这样一个算子
    aggregate(zeroValue, seqOp, combOp)
    zeroValue是每个节点相加的初始值,seqOp为每个节点上调用的运算函数,combOp为节点
    返回结果调用的运算函数。

    sc = spark.sparkContext
    import numpy as np
    rdd = sc.parallelize(np.arange(11),3)
    rdd.collect()
    rdd.aggregate(0,lambda x,y:x+y,lambda x,y:x+y)
    rdd.aggregate(8,lambda x,y:x+y,lambda x,y:x+y)
    rdd.aggregate(3,lambda x,y:x+y,lambda x,y:x+y)
    

    在这里插入图片描述
    从结果看到每个分区上调用seqOp函数都要加上zeroValue,最后运行combOp也要加上zeroValue。3个分区加上最后的combOp所以总共加了四次zeroValue。

  3. aggregateByKey(zeroValue, seqFunc, combFunc, numPartitions=None, partitionFunc=<function portable_hash>)这个方法用来对相同的key值进行聚合操作,同样的是指定zeroValue,seqFunc,numPartitoins为分区数,partitionFunc为作用在分区上的函数。这个方法同aggregate方法名字相似,但是它却是一个transformation方法,不会触发作业的提交!

    datas = [('a',22),('b',33),('c',44),('b',55),('a',66)]
    rdd = sc.parallelize(datas,3)
    rdd.collect()
    rdd.aggregateByKey(0,lambda x,y:x+y,lambda x,y:x+y)
    rdd.aggregateByKey(1,lambda x,y:x+y,lambda x,y:x+y,1).collect()
    

    在这里插入图片描述
    在这里插入图片描述

  4. 继续讲解action算子,collect方法
    该方法会触发作业的提交,返回一个结果的列表,注意:若结果集较大,使用collect方法
    可能使driver程序崩溃,因为collect方法会返回所有节点的结果数据到driver节点,造成OOM
    或其他的异常。
    rdd.collect()

  5. collectAsMap()这个方法仍然是action方法,会触发作业的执行,顾名思义该方法返回的结
    果是一个字典结构

    dd = rdd.collectAsMap()
    type(dd)
    dd
    

    注意这个方法对于键值对的数据,若键存在相同的情况,将发生覆盖!
    在这里插入图片描述

  6. count()方法,统计RDD中元素的个数
    rdd.count()
    在这里插入图片描述

  7. countApprox(timeout, confidence=0.95)
    带有超时限制的count统计函数,时间一到,即便所有任务还没有完成,该方法也会返回已经完
    成的任务的统计结果。

    rdd = sc.parallelize(range(1000000), 100)
    rdd.countApprox(1000, 1.0)
    

    对于不同的时间,返回结果是不一样的!
    在这里插入图片描述

  8. countApproxDistinct(relativeSD=0.05)
    返回大概的RDD数据集中没有重复数据的数据条数。

    rdd1 = sc.parallelize(range(1000000), 100)
    rdd2 = sc.parallelize(np.arange(1,1000001),100)
    rdd3 = sc.union([rdd1,rdd2])
    rdd3.countApproxDistinct()
    rdd3.countApproxDistinct(relativeSD=0.01)
    rdd3.countApproxDistinct(relativeSD=0.001)
    

    在这里插入图片描述

  9. countByKey()
    统计相同key的个数,以字典形式返回

    datas = [('a',11),('b',22),('b',88),('c',56)]
    rdd = sc.parallelize(datas,3)
    rdd.countByKey()
    

    在这里插入图片描述

  10. countByValue()统计值出现的次数,以值为键,次数为值返回字典

    data = ['a','b','c','d','a','a','a','b','c']
    rdd = sc.parallelize(data,3)
    rdd.countByValue()
    
  11. first()返回RDD中的第一条记录

    rdd = sc.parallelize(range(10))
    rdd.first()
    rdd = sc.emptyRDD()
    rdd.first()
    

    注意emptyRDD调用是会报错的!
    在这里插入图片描述

  12. fold(zeroValue, op),该方法使用给定的zeroValue和op方法,先聚合每一个partitons中的
    记录,然后全局聚合

    rdd = sc.parallelize(range(11),3)
    rdd.fold(0,lambda x,y:x+y)
    rdd.fold(1,lambda x,y:x+y)
    

该方法类似于aggragete方法,但是aggragete方法需要提供两个op,而fold方法只需要提供
一个op即可!

在这里插入图片描述

  1. foreach(f)在RDD中的每个元素上应用f方法
sc.parallelize(range(100),3).foreach(lambda x:x**3)

该方法确实是action方法,但是用处不是特别大

  1. foreachPartition(f)在每个分区上应用一个方法f,这个方法就很有用了,例如可以在该
    方法中建立与关系型数据库的链接,将数据保存到mysql或其他数据库中。
def f(iter):
	link to mysql
	for i in iter:
		save to mysql xxxx
		sc.parallelize(range(10),3).foreachPartition(f)
  1. vgetNumPartitions(),这个方法不是action方法,但是可以得到RDD上的分区数,立即执
    行有返回值!
rdd = sc.parallelize(range(100),3)
rdd.getNumPartitions()
  1. getStorageLevel()得到当前RDD的缓存级别
rdd.getStorageLevel()
print(rdd.getStorageLevel())
  1. id()返回该RDD的唯一id值
    rdd.id()

  2. vhistogram(buckets)通过设置的bin区间,返回对应的直方图数据。结果为一个二元tuple,
    tuple第一个元素为区间,第二个元素为区间上元素个数。

  3. isCheckpointed()返回该RDD是否checkpointed了

  4. isEmpty()返回该RDD是否为empy的RDD ,即RDD中没有元素。

rdd1 = sc.emptyRDD()
rdd1.isEmpty()
  1. vlookup(key)由key值在RDD中查找数据
rdd = sc.parallelize([('a',1),('b',2),('c',3),('a',11)],3)
rdd.lookup('a')
rdd.lookup('b')

22.mean()返回RDD中元素的均值

rdd = sc.parallelize(range(20),3)
rdd.mean()

23.vmeanApprox(timeout, confidence=0.95)在给定时间内按置信度计算均值,属于过时不候类
型!

rdd = sc.parallelize(range(2000000),100)
rdd.mean()
rdd.meanApprox(100)

24.vmin(key=None)返回RDD中的最小值

rdd.min()

25.name()返回RDD的名称

rdd.setName('myrdd')
rdd.name()

26.reduce(f)使用指定的方法对RDD中的数据进行聚合操作
rdd = sc.parallelize(range(20),100)
rdd.reduce(lambda x,y:x+y)
sum(rdd.collect())
可以从operator模块导入add二元操作函数,直接用于求和,更加简洁!
from operator import add
rdd.reduce(add)
27.reduceByKeyLocally,通过key进行聚合计算,返回一个字典结构
rdd = sc.parallelize([(“a”, 10), (“b”, 19), (“a”, 88)],3)
rdd.reduceByKeyLocally(add)
28.sampleStdev()计算RDD中元素的标准差,注意样本的标准差除的是N1
而不是样本个数N
rdd = sc.parallelize(np.arange(1,10,2),3)
rdd.sampleStdev()
验证除的是N1
而不是N
29.sampleVariance()RDD中元素的方差,同sampleStdev方法类似,除的是N1
rdd = sc.parallelize(np.arange(1,10,2),3)
rdd.sampleVariance()
30. saveAsPickleFile使用pyspark.serializers.PickleSerializer序列化器将RDD数据
持久化,使用sparkcontext的pickleFile读取
sc.parallelize(range(100),3).saveAsPickleFile(’/datas/pickles/ccc’, 5)
sorted(sc.pickleFile(’/datas/pickles/ccc’, 3).collect())
31.saveAsTextFile并指定压缩格式
sc.pickleFile(’/datas/pickles/bbb’,
3).saveAsTextFile(’/datas/compress/test’,‘org.apache.hadoop.io.compress.GzipCodec’)
sc.pickleFile(’/datas/pickles/bbb’, 3).saveAsTextFile(’/datas/compress/test_abc’)
32.saveAsSequenceFile(path, compressionCodecClass=None)将RDD保存为序列文件,注
意:只能保存key,value结构的RDD数据!可以指定compressionCodecClass
为"org.apache.hadoop.io.compress.GzipCodec"
rdd = sc.parallelize(range(100),3).map(lambda x:(x,str(x)+’_hello’))
rdd.saveAsSequenceFile(’/datas/compress/sequencefile’)
查看hdfs目录
保存后使用sparkcontext的sequenceFile进行读取
sc.sequenceFile(’/datas/compress/sequencefile’).collect()
33stats()返回一个StatCounter 对象,它包含RDD元素的均值,方差等信息。
rdd = sc.parallelize(range(100),3)
rdd.stats()
34.stdev()计算RDD元素的标准差。注意该方法除的是N,而sampleStdev除的确是N1
.
35.sum()求RDD中所有元素的和
36.sumApprox(timeout, confidence=0.95)带有超时限制的求和估计方法
rdd = sc.parallelize(range(10000),300)
rdd.sumApprox(1)
rdd.sum()
37.take(num)获取RDD前num条数据
rdd.take(10)
38.takeOrdered(num, key=None)按照某种顺序取出num条数据,排序方法可以由key关键字
指定。
rdd = sc.parallelize([2,1,3,6,9,1,3,5,6,7,2,3],3)
rdd.takeOrdered(5)
rdd.takeOrdered(5,key=lambda x:-x)
39.takeSample(withReplacement, num, seed=None)从RDD数据集中采样,
withReplacement指定是否有放回,num指定采样个数,seed指定采样的种子,便于结果复
现!
rdd.takeSample(True,10,1)
rdd.takeSample(True,10,1)
rdd.takeSample(True,10,2)
40.toDebugString()返回RDD的调试模式的字符描述
rdd.toDebugString()
41.toLocalIterator()将RDD中的元素返回为本地可迭代数据集,因此要保证本地内存足够
大,能满足存放数据的需要。
42.top(num, key=None)返回RDD中从大到小排序的前num个,默认降序排列,可以通过关键
参数key指定排序方式,数据量太大的时候,需要注意内存是否满足!
rdd = sc.parallelize([2,1,3,6,9,1,3,5,6,7,2,3],3)
rdd.top(5)
rdd.top(5,key=lambda x:-x)
43.treeAggregate(zeroValue, seqOp, combOp, depth=2)该方法实现了多层次的树算法来对
数据进行聚合,使用类似于aggregate方法。
from operator import add
rdd = sc.parallelize([2,1,3,6,9,1,3,5,6,7,2,3],3)
rdd.treeAggregate(0,add,add,4)
rdd.treeAggregate(0,add,add,5)
rdd.treeAggregate(0,add,add,50)
rdd.treeAggregate(0,add,add,2)
rdd.treeAggregate(1,add,add,2)
rdd.treeAggregate(1,add,add,4)
rdd.treeAggregate(2,add,add,4)
44.treeReduce(f, depth=2)实现了多层次的树模型算法来提升速度,使用同reduce方法类
似。
from operator import add
rdd = sc.parallelize([2,1,3,6,9,1,3,5,6,7,2,3],3)
rdd.treeReduce(add,3)
rdd.treeReduce(add,4)
45.variance()返回方差,注意和sampleVariance方法的区别,sampleVariance这个方法除
的是N-1而variance除的是N
rdd.variance()
rdd.sampleVariance()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值