目录
前言
一、什么是Spark?
Spark是一个分布式计算平台,用scala语言编写的计算框架,基于内存的快速、通用、可扩展的大数据分析引擎,它能够高效地处理大规模数据,并支持多种数据处理模式,如批处理、交互式查询、流处理和机器学习等。在大数据领域得到了广泛的应用,在云计算、企业数据分析、实时数据处理和机器学习等方面发挥了重要作用,它的出现极大地简化了大数据处理的复杂性,提高了数据处理的效率和准确性。
二、什么是Scala?
Scala是一门多范式的编程语言,一种类似java的编程语言 ,设计初衷是实现可伸缩的语言 、并集成面象对象编程的各种特性,将面向对象和函数式编程结合成一种简洁的高级语言。Scala的静态类型有助于避免复杂应用程序中的错误,它的JVM和JavaScript运行时让你可以轻松地访问庞大的库生态系统来构建高性能系统,Scala在众多领域得到了广泛的应用,特别是在大数据处理、分布式计算和机器学习方面。
三、项目的实现过程
1、项目要求
2、数据来源
阿里天池数据集:Cosmetics datasets 化妆品数据集_数据集-阿里云天池
3、需求指标
6个相关的统计指标:
①计算价格范围。分别计算护肤品价格的最小值、最大值、平均值、中位数。
②分析品牌分布。统计每个品牌出现的次数,按照次数降序排序,取第一行作为最常见的品牌。
③分析适用皮肤类型分布。定义一个皮肤类型的标签列表,统计到每个皮肤类型的数量,并构建一个“皮肤类型-数量”的映射表。
④分析成分。按照成分进行分组,并统计每个成分出现的次数,按次数降序排序,取第一行的成分作为最常见的成分。
⑤分析排名变化最大的品牌。使用sliding函数将连续的两行作为一对进行切片,对每一对数据进行处理,计算两个排名之间的变化,并记录对应的品牌。
⑥判断排名变化方向。根据最大的排名变化,判断排名是上升还是下降。
4、实现流程
1.构造spark的入口函数sparksession,得到一个spark实例
val spark: SparkSession = SparkSession
.builder()
.appName("Cosmetics Analysis")
.master("local")
.getOrCreate()
2.读取数据
// 设置CSV文件名
val filename: String = "src/main/resources/cosmetics.csv"
val df: DataFrame = spark.read
.option("header", "true")
.option("inferSchema", "true")
.csv(filename)
3.计算护肤品Price列的最小值、最大值、平均值和中位数
// 计算Price列的最小值、最大值、平均值和中位数
val minPrice: Double =
df.selectExpr("min(Price)").first().getAs[Any](0).toString.toDouble
val maxPrice: Double =
df.selectExpr("max(Price)").first().getAs[Any](0).toString.toDouble
val averagePrice: Double =
df.selectExpr("avg(Price)").first().getAs[Any](0).toString.toDouble
val medianPrice: Double =
df.stat.approxQuantile("Price", Array(0.5), 0.01)(0)
4.根据Brand列分组,计算每个品牌的数量,并按照数量降序排序,取第一行作为最常见的品牌
val mostCommonBrand: String =
df.groupBy("Brand").count().orderBy(desc("count")).first().getString(0)
5. 根据皮肤类型的标签列表,计算每个皮肤类型的数量,并返回一个“皮肤类型-数量的映射表”
val skinTypeCounts: Map[String, Long] = skinTypeLabels.map {
label: String =>
val colName: String = s"${label}_count"
val count: Long = df.select(label).where(df(label) === 1).count()
label -> count
}.toMap
6.对DataFrame中的Ingredients列进行explode操作,生成单独的成分列,然后按照成分进行分组,计算每个成分的数量,最后按照数量降序排序
val ingredientCounts: DataFrame = df
.selectExpr("explode(split(Ingredients, ',')) as Ingredient")
.groupBy("Ingredient")
.count()
.orderBy(desc("count"))
7.获取第一行的成分作为最常见的成分
val mostCommonIngredients: String = ingredientCounts.first().getString(0)
8.获取每两个行之间的排名变化列表
val rankChangesWithBrand: List[(Double, String)] = df
.select("Brand", "Rank")
.collect()
.sliding(2)
.map { pair: Array[Row] =>
val rankChange: Double = pair(1).getAs[Any](1).toString.toDouble - pair(
0
).getAs[Any](1).toString.toDouble
val brand: String = pair(1).getAs[String](0)
(rankChange, brand)
}.toList
9.找到排名变化最大的一对,并获取最大的排名变化和对应的品牌
val (maxRankChange, brandWithMaxRankChange) =
rankChangesWithBrand.maxBy((_: (Double, String))._1)
10.判断排名变化是上升还是下降
val rankChangeDirection: String = if (maxRankChange > 0) "上升" else "下降"
11.打印结果
println("价格范围:" )
println("最低价格为" + minPrice)
println("最高价格为" + maxPrice)
println("平均价格为" + averagePrice)
println("中位数价格为" + medianPrice)
println("品牌分布:")
println("最常见的品牌是" + mostCommonBrand)
println("适用皮肤类型分布:")
skinTypeCounts.foreach { case (label, count) => println(s"$label: $count") }
println("成分分析:")
println("最常见的成分是" + mostCommonIngredients)
println("排名变化最大的品牌是" + brandWithMaxRankChange)
println("排名变化为" + maxRankChange)
println("呈" + rankChangeDirection + "变化")
// 停止SparkSession
spark.stop()
输出结果:
四、总结
Scala是一门非常强大和灵活的编程语言,它结合了面向对象和函数式编程的优点,具有丰富的语法和类型系统。学习Scala可以帮助你更好地理解并开发编程、类型推断、模式匹配、函数式编程等概念。总之,学习Scala可以提高编程技能,更好地理解和应用面向对象编程、函数式编程、并发编程等概念。同时,Scala在大数据处理、Web开发等领域也有广泛的应用,学习Scala可以为未来的职业发展带来更多的机会。