1.在spark中用reduce计算10!
用reduce()操作一个字符串,内容是前边练习中所哟以M开头的名字,list以逗哈分隔 。
有一个很有用的操作,有时候我们需要重复使用某个RDD结果,但一遍遍重复计算显然是要开销的,所以我们可以通过一个叫cache()的操作把它杂事存储在内存中
import numpy as np
numRDD = sc.parallelize(np.linesapce(1.0,10.0,10))
sRDD= numRDD.map(lambda x :x **2)
sRDD.cache() #reduce,count都是action,如果这个地方不用cache,sRDD将被激活两次
avg = sRDD.reduce(lambda x,y:x+y)/sRDD.count()
print(avg)
缓存RDD结果对于重复迭代的操作非常有用
2. 针对更复杂结构的transformations和actions
当遇到更为复杂的结构,比如非常将带您的以元组形式组织的k-v对,我们把它叫做pair RDDs,而Spark中针对这种item结构的数据,定义了一些transformations和action
- groupByKey([numTasks]): 返回(K,Seq[V]),也就是hadoop中reduce函数接受的key-valuelist
- reduceByKey(func, [numTasks]): 就是用一个给定的reduce func再作用在groupByKey产生的(K,Seq[V]),比如求和,求平均数
- sortByKey([ascending], [numTasks]) 按照key来进行排序,是升序还是降序,ascending是boolean类型
- countByKey(): 返回的是key对应的个数的一个map,作用于一个RDD
- collectionAsMap():和collect有些类似,但返回的是k-v的字典
完成词频统计
rdd = sc.parallelize(["Hello hello","Hello New York","York says hello"])
resultRDD =(
rdd
.flatmap(lambda x:x.split(" "))
.map(lambda word:word.lower())
.map(lambda word:(word,1))
.reduceByKey(lambda x,y:x+y)
)
resultRDD.collect()
>结果
>[('says',1),('new',1),('hello',4),('york',2)]
#将结果以k-v的形式返回
result = resultRDD.collectionAsMap()
result
>结果
>{'says':1,'new':1,'hello':4,'york':2}
#获取出现频率最高的两个词
print(resultRDD
.sortBy(keyfunc=lambda(word,count):count,ascending=False)
.take(2))
>结果
>[('hello',4),('york',2)]
3.使用spark统计1950到2000年,美国有相同姓名的人出生数目,输出前20个频率最高的名字
还可以在给定2个pairRDD后,通过类似SQL的方式去join它们
homesRDD = sc.parallelize([
('henan',"laz"),
("beijing","zal"),
("shanghai","yf"),
("shanghai","yf")
])
lifeRDD= sc.parallelize([ #生活质量
('henan',10),
("beijing",7),
("shanghai",5),
])
homeRDD.join(lifeRDD).collect()
homeRDD.leftOutjoin(lifeRDD).collect()
>结果