当数据集以键值对形式组织的时候,聚合相同的键的元素进行一些统计是很常见操作,如基本RDD上的fold() combine() reduce()等行动操作,pairRDD上则有相应的针对键的转化操作,Spark上有一组类似的操作,可用组合具有相同键的值,这些操作返回RDD 但它们是转化操作而不是行动操作

reduceByKey()与reduce()相当类似,它接收一个函数,并使用函数对值进行合并,reduceByKey()会为数据集中每个键进行并行规约操作,每个规约操作会将键相同的值合并起来,因为数据集可能很大,因此reduceByKey()没有实现向用户程序返回值的行动操作,而是返回一个由各个键和对应键规约出结果值组成的新RDD

——使用Scala中reduceByKey()和mapValue()计算每个键的平均值

rdd.mapvalues(x=>(x,1)).reduceByKey((x,y)=>(x._1+y._1,x._2+y._2))
key value
panda 0
pink 3
pirate 3
panda 1
pink 4

执行mapValue

key value
panda (0,1)
pink (3,1)
pirate (3,1)
panda (1,1)
pink (4,1)

执行reduceByKey()进行聚集

key value
panda (1,2)
pink (7,2)
pirate (3,1)

使用MapReduce中的合并器combiner,调用reduceByKey()和foldByKey()会在为每个键计算全局总结果前先自动在每台机器上本地合并

——经典分布式单词计数问题

采用flatmap()来生成以单词为键,以数字1为值得pairRDD 之后采用reduceByKey()对单词进行规约计数

Spark pairRDD的聚合操作一

JavaRDD<String> input=sc.textFile("test.txt");
JavaRDD<String> words=input.flatMap(
		new FlatMapFunction<String,String>()
		{
			public Iterable<String> call(String x)
			{
				return Arrays.asList(x.split(" "));
			}
		}
		);//拆分RDD
JavaPairRDD<String,Integer> result=words.mapToPair
{
	new PairFunction<String,String,Integer>()
	{
		public Tuple2<String,Integer> call(String x)
		{
			return new Tuple2(x,1);
		}
	}
	
}.reduceByKey(
		new Function2<Integer,Integer,Integer>()
		{
			public Integer call(Integer a,Integer b)
			{
				return a+b;
			}
		}

		);//调用reduce按照key相同进行规约

 

 

 

相关文章: