项目背景说明
餐饮外卖平台的核心价值体现在配送,而配送的价值则依赖于商家与客户的双向选择。外卖平台通常会通过内容激活消费者和商家两个群体的活跃度。消费者会参考平台展示的内容选择商家,商家也会以消费者评价与平台统计数据为依据调整策略,由此再吸引更多的用户下单、评论、形成正向循环。保证配送的时效与品质是从优化用户体验的角度,吸引更多的用户参与,进而带动商家不断入驻。由此,商家、消费者、骑手在平台上形成越来越多的真实可靠的数据,帮助消费者更好的做出消费决策,同时促进商家提高服务质量。而平台通过数据,不断调整优化服务,从而不断提升这种多边网络效应。提升网络效应的直接结果就是用户和商家规模大幅提升,进而形成规模效应——降低获客成本、提高效益,并且不断提升自己的行业壁垒。
为探索各大外卖平台的市场策略与经营模式,现已从及平台获取到了原始数据集,包含“id,request_id,walle_id,retailer_id,retailer_name,retailer_address,etailer_location,city_id,city_name,grid_id,carrier_id,team_id,applicant_id,applicant_name,first_auditor_role,first_auditor_candidate_ids,first_auditor_id,first_auditor_name,second_auditor_role,second_auditor_candidate_ids,second_auditor_id,second_auditor_name,status,max_distance_before_edit,min_distance_before_edit,max_distance_after_edit,min_distance_after_edit,area_before_edit,area_after_edit,created_at,updated_at,申请时间,创建时间”等字段,为保障用户隐私和行业敏感信息,已经对数据脱敏。数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。在涉及客户安全数据或一些商业性敏感数据的情况下,对真实数据进行改造并提供测试使用,如身份证号、手机号等个人敏感信息都需要进行数据脱敏。本题已将脱敏后的数据存放于Master节点/chinaskills目录下。任务中所有命令务必使用绝对路径。
任务一:数据清洗
子任务2
任务背景:
数据的维数是指数据具有的特征数量,数据特征矩阵过大, 将导致计算量比较大,训练时间长的等问题。当数据存在冗余属性时,对多余属性剔除的过程,称为“数据降维”。降维的好处十分明显,它不仅可以数据减少对内存的占用,还能够加快学习算法的执行与收敛。请根据任务具体要求,针对原始数据集中可能存在的冗余属性进行排查,复制并保存结果。
任务描述:
请使用子任务1的结果数据作为数据源,判断属性“申请时间”、“创建时间”与“created_at”、“updated_at”是否为重复属性。请按照如下要求编写Spark程序对数据进行清洗,并将结果输出/diliveryoutput2(将分区数设置为1)。
1) 分析数据文件
2) 排除属性列“申请时间”、“创建时间”与“created_at”、“updated_at”是否为重复属性
3) 程序打包并在Spark平台运行
具体任务要求:
1、利用/diliveryoutput1作为源数据,使用hadoop shell命令查看数据集条数,请将查看命令及结果复制并粘贴至对应报告中。
2、如果仅考虑年、月、日数据,忽略时刻信息,“申请时间”、“创建时间”与“created_at”、“updated_at”是否为重复属性?请编写Spark程序,并在程序中以打印语句输出两对属性对应相等的数据条数。将打印输出结果以及你的结论复制并粘贴至对应报告中。(复制内容需包含打印语句输出结果的上下各 5 行运行日志)。
示例格式:
===两组属性同时相等的数据条数为*条===
结论:“申请时间”、“创建时间”与“created_at”、“updated_at”(是/不是)重复属性。
如果数据相等的比例超过原始数据集的90%,则剔除属性“created_at”与“updated_at”, 并将结果数据集json文件保存至/diliveryoutput2。
package eat
import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql.{DataFrame, SparkSession}
object two {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder().master("local[6]").appName("two").config("spark.sql.warehouse.dir", "C:/").getOrCreate()
Logger.getLogger("org").setLevel(Level.ERROR)
val datas: DataFrame = spark.read.json("data/output/diliveryoutput1")
// val data: RDD[Row] = datas.rdd
// import spark.implicits._
// val result: RDD[Array[String]] = data.map(_.mkString(",")).map(_.split(","))
// .filter(item => {
// var i = 0
// for (r <- item) {
// if (item.equals("申请时间") == item.equals("created_at") && (item.equals("创建时间") == item.equals("updated_at"))) {
// println(item.toString)
// }
// }
// i != 0
// }
// )
//
// result.foreach(println)
datas.createOrReplaceTempView("time")
// val sql =
// """
// |select * from time where left(`申请时间`,10)= left(created_at,10) and left(`创建时间`,10) = left(updated_at,10)
// |""".stripMargin
//select * from time where left('申请时间',10) = left('created_at',10) && left('创建时间',10) = left('updated_at',10)
// spark.sql(sql).show()
spark.udf.register("match", (time: String) => {
time.substring(0, time.indexOf(" "))
})
val sql =
"""
|select * from time where match(`申请时间`) = match(`创建时间`) and match(`created_at`) = match(`updated_at`)
|""".stripMargin
val num: Long = spark.sql(sql).count()
if (num > datas.count() * 0.9) {
val result: DataFrame = datas.drop("created_at", "updated_at")
// result.write.json("hdfs://192.168.231.100:9000/diliveryoutput2")
result.repartition(1).write.json("data/output/diliveryoutput2")
} else
datas.repartition(1).write.json("data/output/diliveryoutput2")
println(s"===两组属性同时相等的数据条数为${num}条===")
}
}