RDD有两种类型的操作 ,分别是Transformation(返回一个新的RDD)和Action(返回values)。
1.Transformation:根据已有RDD创建新的RDD数据集build
(1)map(func):对调用map的RDD数据集中的每个element都使用func,然后返回一个新的RDD,这个返回的数据集是分布式的数据集。
(2)filter(func) :对调用filter的RDD数据集中的每个元素都使用func,然后返回一个包含使func为true的元素构成的RDD。
(3)flatMap(func):和map很像,但是flatMap生成的是多个结果。
(4)mapPartitions(func):和map很像,但是map是每个element,而mapPartitions是每个partition。
(5)mapPartitionsWithSplit(func):和mapPartitions很像,但是func作用的是其中一个split上,所以func中应该有index。
(6)sample(withReplacement,faction,seed):抽样。
(7)union(otherDataset):返回一个新的dataset,包含源dataset和给定dataset的元素的集合。
(8)distinct([numTasks]):返回一个新的dataset,这个dataset含有的是源dataset中的distinct的element。
(9)groupByKey(numTasks):返回(K,Seq[V]),也就是Hadoop中reduce函数接受的key-valuelist。
(10)reduceByKey(func,[numTasks]):就是用一个给定的reduce func再作用在groupByKey产生的(K,Seq[V]),比如求和,求平均数。
(11)sortByKey([ascending],[numTasks]):按照key来进行排序,是升序还是降序,ascending是boolean类型。
2.Action:在RDD数据集运行计算后,返回一个值或者将结果写入外部存储
(1)reduce(func):就是聚集,但是传入的函数是两个参数输入返回一个值,这个函数必须是满足交换律和结合律的。
(2)collect():一般在filter或者足够小的结果的时候,再用collect封装返回一个数组。
(3)count():返回的是dataset中的element的个数。
(4)first():返回的是dataset中的第一个元素。
(5)take(n):返回前n个elements。
(6)takeSample(withReplacement,num,seed):抽样返回一个dataset中的num个元素,随机种子seed。
(7)saveAsTextFile(path):把dataset写到一个textfile中,或者HDFS,或者HDFS支持的文件系统中,Spark把每条记录都转换为一行记录,然后写到file中。
(8)saveAsSequenceFile(path):只能用在key-value对上,然后生成SequenceFile写到本地或者Hadoop文件系统。
(9)countByKey():返回的是key对应的个数的一个map,作用于一个RDD。
(10)foreach(func):对dataset中的每个元素都使用func。
在启动spark-shell之前,需将数据文件上传至hdfs上
hadoop fs -mkdir -p /dir
hadoop fs -put /data/file /dir
在spark-shell上操作
rdd.repartition(1).saveAsTextFile("hdfs://localhost:9000/dir/out.txt")
mkdir -p /data
hadoop fs -get /dir/out.txt/part-00000 /data/ans20_ans1.txt
使用Spark shell对数据进行WordCount统计、去重、排序、求平均值以及Join操作。
加载数据,将数据变成RDD
val rdd = sc.textFile("hdfs://localhost:9000/dir/file");
筛选出指定数据(示例为id为20054的数据)
val x=rdd.filter(line=> line.contains('20054'))
统计第0列的数据进行词频统计
rdd.map(line=> (line.split('\t')(0),1)).reduceByKey(_+_).collect
对第1列数据进行去重
rdd.map(line => line.split('\t')(1)).distinct.collect
根据第0列进行升序排序,输出第1列数据 (false为降序)
rdd.map(line => ( line.split('\t')(1).toInt, line.split('\t')(0) ) ).sortByKey(true).collect
#提取文件1的第0列和第2列
val rdd11 = rdd1.map(line=> (line.split('\t')(0), line.split('\t')(2)) )
#提取文件1的第1列和第2列
val rdd22 = rdd2.map(line=> (line.split('\t')(1), line.split('\t')(2)) )
将rdd11以及rdd22中的数据,根据Key值,进行Join关联,得到最终结果
val rddresult = rdd11 join rdd22
最后将结果输出,查看输出效果
rddresult.collect
goods表:商品ID(goods_id),商品状态(goods_status),商品分类id(cat_id),评分(goods_score)
goods_visit表:商品ID(goods_id),商品点击次数(click_num)
商品表(goods)及商品访问情况表(goods_visit)可以根据商品id进行关联。
现在统计每个分类下,商品的平均点击次数是多少?
#提取文件1的第0列和第2列
val rdd11 = rdd1.map(line=> (line.split('\t')(0), line.split('\t')(2)) )
#提取文件1的第0列和第1列
val rdd22 = rdd2.map(line=> (line.split('\t')(0), line.split('\t')(1)) )
合并两表
val rddjoin = rdd11 join rdd22
用collect()方法查看rddjoin的结果
rddjoin.collect
在大表的基础上,进行统计。得到每个分类,商品的平均点击次数。
rddjoin.map(x=>{(x._2._1, (x._2._2.toLong, 1))}).reduceByKey((x,y)=>{(x._1+y._1, x._2+y._2)}).map(x=>{(x._1, x._2._1*1.0/x._2._2)}).collect
Spark Shell简单使用
Spark Shell 的使用
Spark 大数据文本统计
spark 累加历史 + 统计全部 + 行转列