SparkCore实现分类计数|分组TopN|分组平均

package exercise

import org.apache.spark.{SparkConf, SparkContext}

/**
 * @ClassName: Exec03
 * @Description: 
 * @Author: xuezhouyi
 * @Version: V1.0
 **/
object Exec03 {
	def main(args: Array[String]): Unit = {
		val conf = new SparkConf().setAppName(Exec03.getClass.getSimpleName).setMaster("local[*]")
		val sc = new SparkContext(conf)

		val list = List(
			"AA 张三 25 男 语文 50",
			"AA 张三 25 男 数学 60",
			"AA 张三 25 男 英语 70",
			"AA 李四 20 男 语文 50",
			"AA 李四 20 男 数学 50",
			"AA 李四 20 男 英语 50",
			"AA 王芳 19 女 语文 70",
			"AA 王芳 19 女 数学 70",
			"AA 王芳 19 女 英语 70",
			"BB 张大三 25 男 语文 60",
			"BB 张大三 25 男 数学 60",
			"BB 张大三 25 男 英语 70",
			"BB 李大四 20 男 语文 50",
			"BB 李大四 20 男 数学 60",
			"BB 李大四 20 男 英语 50",
			"BB 王小芳 19 女 语文 70",
			"BB 王小芳 19 女 数学 80",
			"BB 王小芳 19 女 英语 70"
		)
		val rdd = sc.parallelize(list).map(
			line => {
				val strings = line.split("\\s+")
				new Student(strings(0), strings(1), strings(2).toInt, strings(3), strings(4), strings(5).toInt)
			}
		)

		_funcCount
		/* 总数:6,小于20岁:2,等于20岁:2,大于20岁:2,男生:4,女生:2,AA班有:3,BB班有:3 */

		_funcTOP(3)
		/*
			科目:数学,最高分:80,是:王小芳
			科目:英语,最高分:70,是:张三
			科目:语文,最高分:70,是:王芳
		 */

		_funcAVG
		/*
			科目:数学,平均分:63
			科目:语文,平均分:58
			科目:英语,平均分:63
		 */

		_funcClassSubjectAVG
		/*
			班级:AA,科目:英语,平均分:63
			班级:AA,科目:语文,平均分:56
			班级:AA,科目:数学,平均分:60
			班级:BB,科目:语文,平均分:60
			班级:BB,科目:数学,平均分:66
			班级:BB,科目:英语,平均分:63
		 */

		sc.stop()

		/*------------------------------------------------------------------------------------------------------------------*/
		/* 计算总数 */
		def _funcCount: Unit = {
			val ret = rdd.map(e => {
				new Student(className = e.className, name = e.name, age = e.age, gender = e.gender)
			}).distinct()
				.map(e => {
					val total = 1
					val less = if (e.age < 20) 1 else 0
					val equal = if (e.age == 20) 1 else 0
					val great = if (e.age > 20) 1 else 0
					val male = if (e.gender == "男") 1 else 0
					val female = if (e.gender == "女") 1 else 0
					val class12 = if (e.className == "AA") 1 else 0
					val class13 = if (e.className == "BB") 1 else 0
					(total, less, equal, great, male, female, class12, class13)
				})
				.reduce {
					case ((a1, b1, c1, d1, e1, f1, g1, h1), (a2, b2, c2, d2, e2, f2, g2, h2)) =>
						(a1 + a2, b1 + b2, c1 + c2, d1 + d2, e1 + e2, f1 + f2, g1 + g2, h1 + h2)
				}
			println(s"总数:${ret._1}人,小于20岁:${ret._2}人,等于20岁:${ret._3}人,大于20岁:${ret._4}人,男生:${ret._5}人,女生:${ret._6}人,AA班有:${ret._7}人,BB班有:${ret._8}人")
		}

		/* 计算第一名 */
		def _funcTOP(n:Int): Unit = {
			rdd.sortBy(e => e.score, ascending = false, numPartitions = 1)
				.take(n)
				.foreach {
					case e: Student => println(s"科目:${e.subject},最高分:${e.score},是:${e.name}")
				}
		}

		/* 计算科目平均分 */
		def _funcAVG: Unit = {
			rdd.map(e => (e.subject, (e.score, 1))).reduceByKey {
				case ((score1, count1), (score2, count2)) => {
					(score1 + score2, count1 + count2)
				}
			}.foreach {
				case (subject, (score, count)) => {
					println(s"科目:${subject},平均分:${score / count}")
				}
			}
		}

		/* 班级科目平均分 */
		def _funcClassSubjectAVG: Unit = {
			rdd.map(e => ((e.className, e.subject), (e.score, 1)))
				.reduceByKey {
					case ((score1, count1), (score2, count2)) => (score1 + score2, count1 + count2)
				}
				.foreach {
					case ((className, subject), (score, count)) => println(s"班级:${className},科目:${subject},平均分:${score / count}")
				}
		}
	}
}

/* 班级 姓名 年龄 性别 科目 成绩 */
case class Student(className: String, name: String, age: Int, gender: String, subject: String = "", score: Int = 0)
发布了54 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/DataIntel_XiAn/article/details/101038261
今日推荐