Scala进阶之路-统计商家id的标签数以及TopN示例案例分析

                                    作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.项目需求

  将“temptags.txt”中的数据进行分析,统计出商家id的评论标签数量,由于博客园无法上传大文件的文本,因此我把该文本的内容放在博客园的另一个链接了(需要的戳我),如果网页打不开的话也就可以去百度云盘里下载副本,链接:https://pan.baidu.com/s/1daRiwOVe6ohn42fTv6ysJg 密码:h6er。

  我之前使用Hadoop的MapReduce实现过,详情请参考:https://www.cnblogs.com/yinzhengjie/p/9332761.html,但是实在过于繁琐,在学习Scala的时候发现它实现起来更简单。

二.代码实现

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/ package cn.org.yinzhengjie.scala /**
* 单例模式
*/
object TaggenDemo {
//从json中抽取出所有评论,形成list返回
def extractTags(json:String) :List[String] = {
var list:List[String] = Nil
/**
* 注意这两个判断条件 :json != null && !json.equals("")
* 1>.json != null:
* 首先先说说null,这个null不管是在java还是Scala中它可以赋值给任意的引用数据类型。在调用toString方法时,都会抛
* 空指针异常,即“java.lang.NullPointerException”。
* 2>.!json.equals("")
* 接下来我们说说空字符串(""),这个空字符串("")它的长度为多少呢?很显然空字符串的长度为“0”,那么问题来了,它和null
* 有啥区别呢?打个简单的比方哈,在Java代码中,"String[] arr1 = null;"与"String[] arr2 = new String[0];"的区别你知道吗?
* 估计看到这两句话很多小伙伴已经不需要我多做解释了吧,没错,变量arr1是没有被初始化的,而arr2是被初始化且其长度为0.
*/
if(json != null && !json.equals("")){
import com.alibaba.fastjson.JSON
//构造json对象
val obj = JSON.parseObject(json)
//提取数组属性
val arr = obj.getJSONArray("extInfoList")
if(arr != null && arr.size() > 0){
//提取数组一个json对象
val first = arr.getJSONObject(0)
//标签集合
val tags = first.getJSONArray("values")
if(tags != null && tags.size() > 0){
for(i <- 0 until tags.size()){
list = tags.getString(i) :: list
}
}
}
}
list
}
def main(args: Array[String]): Unit = {
/**
* 读取文件
*/
import scala.io.Source
val f = Source.fromFile("D:\\BigData\\JavaSE\\yinzhengjieData\\temptags.txt")
val lines = f.getLines().toList
/**
* 切割每一行,提取busid ->tags
*/
val var2 = lines.map(line=>{
val arr = line.split("\t")
val busid = arr(0)
val json = arr(1)
(busid , extractTags(json))
})
/**
* 过滤集合的空评论
*/
val var3 = var2.filter(!_._2.isEmpty)
/**
* 压扁var3 , 形成 : (busid,tag)
*/
val var4 = var3.flatMap(t=>{
var l:List[(String,String)] = Nil
for(tag <- t._2){
l = (t._1 , tag) :: l
}
l
})
/**
* 分组统计每个商家每条评论的数量,Map
*/
var var5 = var4.groupBy(t=>t)
/**
* 统计每条评论个数,例如((75144086 , 环境优雅) , 22)
*/
var var6 = var5.toList.map(t=>{
(t._1._1, (t._1._2 ,t._2.size))
})
/**
* 分组,将同一商家的所有评论聚在一起
*/
var var7= var6.groupBy(t=>t._1) /**
* mapValues方法只对value进行变换
*/
var var8 = var7.mapValues(t=>{
t.map(t=>t._2)
})
/**
* 对每个商家的所有评论按照数量倒排序
*/
var var9= var8.mapValues(t=>{
t.sortBy(t=> -t._2 )
})
/**
* 按照上架第一个标签的评论数进行排序
*/
var var10 = var9.toList.sortBy(t=>{
-t._2(0)._2
})
/**
* 取出前10个元素,有两种方式,即take或者slice.是不是发现Scala中实现topN要比Java中的MapReduce要简单的多?
*/
val res = var10.take(10) //当然我们也可以用切片的方式取出该元素: val res = var10.slice(0,10) /**
* 打印我们得到的数据
*/
for(e <- res){
println(e)
}
}
} /*
以上代码执行结果如下:
(75144086,List((8239,60), (服务热情,38), (8241,31), (效果赞,30), (环境优雅,22), (无办卡,22), (性价比高,21), (技师专业,21), (无推销,19), (价格实惠,18), (干净卫生,13), (体验好,12), (韩系风格,10), (美发师手艺好,3), (服务差,2), (美发效果好,1), (效果差,1)))
(77287793,List((干净卫生,29), (音响效果好,26), (环境优雅,26), (价格实惠,25), (交通便利,25), (性价比高,19), (服务热情,18), (高大上,16), (停车方便,13), (体验好,13), (服务一般,1), (音响效果差,1), (朋友聚会,1), (服务差,1)))
(74145782,List((服务热情,18), (味道赞,14), (干净卫生,13), (上菜快,13), (菜品不错,12), (分量足,11), (回头客,11), (环境优雅,11), (性价比高,6), (停车方便,5), (体验好,4), (不推荐,3), (服务差,2), (菜品差,2), (分量少,1), (6,1), (价格实惠,1), (体验差,1)))
(85648235,List((味道赞,17), (服务热情,15), (干净卫生,13), (上菜快,12), (回头客,11), (性价比高,10), (体验好,9), (价格实惠,8), (环境优雅,8), (分量足,7), (情侣约会,1)))
(83073343,List((干净卫生,17), (味道赞,16), (环境优雅,15), (菜品不错,11), (服务热情,11), (肉类好,9), (性价比高,8), (体验好,7), (分量足,7), (回头客,6), (价格实惠,4), (味道一般,1), (分量少,1), (5,1), (服务差,1), (上菜慢,1), (2,1)))
(73607905,List((菜品不错,16), (干净卫生,15), (回头客,15), (味道赞,14), (服务热情,14), (分量足,13), (性价比高,11), (肉类好,11), (环境优雅,7), (体验好,5), (上菜快,5), (体验差,2), (羊蝎子,1), (价格实惠,1)))
(73963176,List((味道赞,15), (价格实惠,12), (分量足,11), (菜品不错,10), (肉类好,7), (干净卫生,7), (服务热情,7), (环境优雅,6), (回头客,4), (性价比高,3), (价格高,1), (服务差,1), (味道一般,1)))
(78824187,List((价格实惠,13), (回头客,11), (分量足,10), (环境优雅,8), (性价比高,8), (干净卫生,7), (上菜快,6), (2,6), (服务热情,5), (主食赞,5), (味道赞,4), (1,1), (3,1), (服务差,1)))
(87994574,List((无推销,12), (价格实惠,8), (干净卫生,7), (服务热情,7), (效果赞,5), (无办卡,5), (环境优雅,4), (技师专业,3), (体验好,2), (没有异味,2), (韩系风格,1), (效果差,1)))
(76893145,List((服务热情,10), (环境优雅,7), (高大上,5), (味道赞,5), (咖啡厅,5), (回头客,4), (温馨浪漫,3), (服务一般,2), (体验好,2), (味道一般,2), (饮品赞,1), (性价比高,1)))
*/

Scala进阶之路-统计商家id的标签数以及TopN示例案例分析的更多相关文章

  1. Hadoop基础--统计商家id的标签数案例分析

    Hadoop基础--统计商家id的标签数案例分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.项目需求 将“temptags.txt”中的数据进行分析,统计出商家id的评论标 ...

  2. Scala进阶之路-Scala中的枚举用法案例展示

    Scala进阶之路-Scala中的枚举用法案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala中的枚举值和Java中的枚举值有点差别,不过使用起来也都差大同小异,我这 ...

  3. Scala进阶之路-Spark独立模式(Standalone)集群部署

    Scala进阶之路-Spark独立模式(Standalone)集群部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们知道Hadoop解决了大数据的存储和计算,存储使用HDFS ...

  4. Scala进阶之路-Spark本地模式搭建

    Scala进阶之路-Spark本地模式搭建 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spark简介 1>.Spark的产生背景 传统式的Hadoop缺点主要有以下两 ...

  5. Scala进阶之路-Spark底层通信小案例

    Scala进阶之路-Spark底层通信小案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spark Master和worker通信过程简介 1>.Worker会向ma ...

  6. Scala进阶之路-Scala高级语法之隐式(implicit)详解

    Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...

  7. Scala进阶之路-高级数据类型之集合的使用

    Scala进阶之路-高级数据类型之集合的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala 的集合有三大类:序列 Seq.集 Set.映射 Map,所有的集合都扩展自 ...

  8. Scala进阶之路-高级数据类型之数组的使用

    Scala进阶之路-高级数据类型之数组的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组的初始化方式 1>.长度不可变数组Array 注意:顾名思义,长度不可变数 ...

  9. Scala进阶之路-Scala的基本语法

    Scala进阶之路-Scala的基本语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数式编程初体验Spark-Shell之WordCount var arr=Array( ...

随机推荐

  1. 重温Servlet学习笔记--response对象

    在用户浏览网页时,服务器对于客户端浏览器做出的响应被封装成一个HttpServletResponse对象,要对浏览器操作只需要操作这个response对象即可.response的功能分类及介绍: 响应 ...

  2. Office 365 - SharePoint 2013 Online之添加App开发工具Napa

    1.新建一个网站集,模板选择开发人员模板,如下图: 2.确定以后,需要稍等一会儿; 3.点击网站内容,添加app,如下图: 4.进入SharePoint Store,选择Napa,如下图: 5.选择A ...

  3. javascript之观码说理

    前一阶段看到大神在网上贴出的测试个人js理解的代码. 在此我在此借用大神的代码,进行自我复述,大神文章参见:http://www.imooc.com/article/1731 代码1: functio ...

  4. linq入门系列导航

    写在前面 为什么突然想起来学学linq呢?还是源于在跟一个同事聊天的时候,说到他们正在弄得一个项目,在里面用到了linq to sql.突然想到距上次使用linq to sql是三年前的事情了.下班回 ...

  5. ubuntu系统mysql.h no such file or directory

    在Ubuntu系统中,你已经安装了mysql,即你使用sudo apt-get install mysql-server mysql-client然而使用C语言访问mysql数据库时,却发现出现了如下 ...

  6. ComboGrid( 数据表格下拉框)

    一. 加载方式//class 加载方式<select id="box" class="easyui-combogrid" name="dept& ...

  7. Windbg程序调试系列1-Mex扩展使用总结

    最近一直在频繁使用Windbg做线上Dump调试,与微软做Case交流的时候,发现微软CSS团队,用了一个非常效率的Windbg 插件,Mex: 使用介绍: https://blogs.msdn.mi ...

  8. Java基础之 运算符

    前言:Java内功心法之运算符,看完这篇你向Java大神的路上又迈出了一步(有什么问题或者需要资料可以联系我的扣扣:734999078) 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,J ...

  9. Kubernetes 安装

    一.引用自:https://www.cnblogs.com/gaoyuechen/p/8685771.html#_label6 二.安装过程中docker 坑 转自:https://blog.csdn ...

  10. checkbox反复调用attr(&#39;checked&#39;, true/false)只有第一次生效

    /** * 全选 */ function checkAll() { $("input[name=ids]").attr("checked", true); } ...