python语言spark弹性分布式数据集-RDD(Spark快速大数据分析)(上)

官方文档:http://spark.apache.org/

1.开始:

Linux命令:spark-submit  加py文件名

py文件开始:

import pyspark

conf=pyspark.SparkConf().setMaster("local").setAppName("My App")
sc=pyspark.SparkContext(conf=conf)

日常使用方法:

collect():返回rdd中的数据。

saveAsTextFile():数据保存操作,把rdd列表里的元素转到文件系统(默认一个元素一行)。传入一个文件地址,文件需要未被创建,原因是如果文件地址不小心相同,可能会发生数据覆盖,数据存在等错误(hadoop权威指南中写的)。

persist():数据持久保持在内存中的操作,spark默认rdd使用一次后就会从内存中移除,好像是模式的原因,先组织好操作步骤(没有先计算),直到行动操作(书上说是reduce,fold,aggregate等会输出的操作,saveAsTextFile,collect等应该也算),然后才计算,用这个(persist)方法,使用后数据仍然保存在内存中。如未使用,想再次用需要再次计算(如,在spark机器学习中对函数的参数进行评估需要重复运算,以找到最合适的参数),重新计算会浪费一些时间和资源,用这个方法后就会保存在内存中,下次就可以直接用。如可以在保持分区的情况,像一些需要混洗的操作(就是需要明确查找,如排序等,需要hash()等分区后,才可以找到),如果频繁使用,每次不但要重新计算,还需要重新hash()分区,浪费时间和资源。后面的操作如果不发生可以改变分区的操作,保存还可以持续。不要担心内存满了怎么办,好像是有机制的吧,很多都是书上写的,具体单机也无从考证,不过挺有道理的。

2.方法:

(1)数据读入方法:

textFile():读取一个文件的地址,以单行为一条数据
wholeTextFiles():读取一个文件夹地址,以其中所有的目标文件为数据,一个文件作为一条二元组型(key-value)数据,文件地址为key,文件内容为value,如:("file///:home/hadoop/spark/test","0\n1\n2\n3\n")
parallelize():传入一个list

注意:文件末尾尽量在数据末尾,随手一个回车就会增加一条数据,数据处理方式不对可能会报错,测试在Linux默认文件系统下完成,其它的文件系统如S3,hdfs等自行测试。

 

(2)单行数据Value处理方法:

map():传入一个方法,这个方法会逐条处理每一条数据,新的集为传入方法return的内容。

count():返回rdd内的数据个数。不是rdd,下面很多如:reduce,fold,aggregate等也是这样。

take():传入一个数字,返回数字个数的元素的rdd。相类似的还有top()。

flatmap():传入一个方法,逐条处理数据,与map()不同的是,return返回的内容如果是list列表,将会被自动切分,如:return ["coffee","panda"]  flatmap()会自动切分成["coffee","panda",加其它数据],而map()会是这样的[["coffee","panda"],加其它数据]。

filter():传入一个函数,在函数体内进行筛选,return一个bool型,返回ture会被保留,其它的不会保留。

countByValue():各元素在rdd中出现的个数,用字典格式包装,如一个"panda"数据,会是这样:defaultdict(<class 'int'>, {"panda":1,其它数据}),和后面countByKey()不同的是,这个Value就是这一条数据,一个元素,如一个("panda",1)数据,会是这样:defaultdict(<class 'int'>, {('panid', 1): 1,其它数据})。

reduce():把所有数据结合成一条数据,传入一个包含两个形参的方法,第一个形参为第一个数据或者前面方法结合的半成品(学名叫Combiner组合器),第二个为后面需要结合的数据,用最简单的lambda写一个累加方法,如:(lambda x,y:x+y)。分区:因为在单机测试,强行通过partitionBy(2)增加一个分区会报没有数据的错误,应该有分区聚合操作,具体不知。

fold():传入一个初始值,可以为其它格式,比如(0,0),再传入一个函数,包含两个形参,第一个形参为初始值或处理后的半成品,第二个为需要处理的数据,如计算平均值:先map(lambda x:(int(x),1)),再fold((0,0),(lambda x,y:(x[0]+y[0],x[1]+y[1]))   最后得到一个二元组(累加数,数据个数),平均值=二元组[0]/二元组[1]。分区:因为是单机模式,强行分区会报数据不足的错误,但根据print打印中间结果分析,每个分区算出各自的结果(使用一次初始值),然后仍然是用传入的函数,用初始值把各分区的结果加起来(再次使用初始值)。

aggregate():传入三个参数,第一个是初始值,第二个是分区内的计算函数,第三个是分区间的计算函数。这个函数结合了map()和fold(),提高了性能,如计算平均值aggregate((0,0),(lambda x,y:(x[0]+int(y),x[1]+1)),(lambda x,y:(x[0]+y[0],x[1]+y[1])))。结果和上面的fold()一样,节省了一步操作,提高了性能。分区:和fold()相似,不同的是分区内和分区间用的不是同一个函数。

distinction():去除rdd中的重复数据,如:[1,2,1,1,1].distinct(),结果是[1,2]。

(3)两个rdd之间的“伪集合操作”(学了一些基础的,没发现“真-集合操作”):

union():传入一个rdd,返回一个包含两个rdd中所有元素的rdd。这个是rdd数据间的相加(+)操作。

subtract():传入一个rdd,返回   使用这个方法的rdd里的数据  移除  和传入rdd中相同的数据。这个是rdd数据间的相减(-)操作。

intersection():仍然只传入一个rdd,返回两个rdd中相同的数据,自带distinction()操作,如:[1,2,3,3].intersection([3,4,5]),结果是[3]。虽然看不出速度咋样,书上说因为需要数据混洗,效率比union()差,想一下也对,毕竟要找相同的元素,随便hash()分区一下也会消耗时间和资源。这个是rdd数据间的相交(倒着的U)操作。

cartesian():还是传入一个rdd,返回两个rdd之间的笛卡儿积,以二元组包装,如:[1,2].cartesian([3,4]),结果是[(1,3),(1,4),(2,3),(2,4)]。这是rdd数据间的相乘(*)操作,没发现相除方法,没有头绪。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值