我们知道,Spark是一个优秀的基于内存的计算框架,可以独立使用,也可以和Hadoop集成使用,可以使用Hadoop的yarn进行资源管理、可以读写hdfs文件,而且Spark 是在 Scala 语言中实现的,它将 Scala 用作其应用程序框架。与 Hadoop 不同,Spark 和 Scala 能够紧密集成,其中的 Scala 可以像操作本地集合对象一样轻松地操作分布式数据集。
自行准备某个领域的数据(可以是电商商品数据、电商订单数据、影视数据、游戏数据、工业互联网数据、手机埋点数据、天气数据、股票数据、房地产数据等等,但不能选新能源车辆数据),并搜集/准备至少五个相关的统计指标,然后写Spark程序完成这些指标的计算。
每当我想尝试新的化妆品时,都很难选择。实际上,这并不困难。有时会令人恐惧,因为我从未尝试过的新产品最终给我造成了皮肤困扰。我们将使用处理丝芙兰上1472种化妆品的成分进行指标统计。使用的阿里天池数据集链接如下:
https://tianchi.aliyun.com/dataset/92538/
val spark: SparkSession = SparkSession
.builder()
.appName("CosmeticsAnalysis")
.master("local")
.getOrCreate()
读取数据集文件,并将DataFrame文件转成df
// 设置CSV文件名
val filename: String = "src/main/resources/cosmetics.csv"
val df: DataFrame = spark.read
.option("header", "true")
.option("inferSchema", "true")
.csv(filename)
计算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)
根据Brand列分组,计算每个品牌的数量,并按照数量降序排序,取第一行作为最常见的品牌
val mostCommonBrand: String =
df.groupBy("Brand").count().orderBy(desc("count")).first().getString(0)
根据皮肤类型的标签列表,计算每个皮肤类型的数量,并返回一个“皮肤类型-数量”的映射表
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
对DataFrame中的Ingredients列进行explode操作,生成单独的成分列,然后按照成分进行分组,计算每个成分的数量,最后按照数量降序排序
val ingredientCounts: DataFrame = df
.selectExpr("explode(split(Ingredients, ',')) as Ingredient")
.groupBy("Ingredient")
.count()
.orderBy(desc("count"))
获取第一行的成分作为最常见的成分
val mostCommonIngredients: String = ingredientCounts.first().getString(0)
获取每两个行之间的排名变化列表
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
找到排名变化最大的一对,并获取最大的排名变化和对应的品牌
val (maxRankChange, brandWithMaxRankChange) =
rankChangesWithBrand.maxBy((_: (Double, String))._1)
判断排名变化是上升还是下降
val rankChangeDirection: String = if (maxRankChange > 0) "上升" else "下降"
打印结果
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 + "变化")
在实现该程序时,要确保环境是否配置好,我这边使用的环境配置文件是spark_lib、scala-2.11.12,小伙伴需要请在评论区留言私信我,我可转发至给你哟。
学习Spark当然可以不用学习Scala,只要有Java语言基础,结合Spark基础框架原理、简单的代码实现一样可以实现开发Spark的目的;但是先于Spark学习Scala却是可以是为了今后快速使用Scala开发出Spark程序;在大数据和机器学习领域,相比与Java或者C++,Scala的语法更容易掌握。
在这学期的学习中,一步一步跟着老师的讲稿做,有时候更多遇到的是出现问题和报错,但最后通过向老师询问和百度解决了一系列的问题。本人对于Spark课程还属于小白阶段,若有不正确的还请小伙伴们指正哟!