Scala进阶之路-统计商家id的标签数以及TopN示例案例分析
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示例案例分析的更多相关文章
- Hadoop基础--统计商家id的标签数案例分析
Hadoop基础--统计商家id的标签数案例分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.项目需求 将“temptags.txt”中的数据进行分析,统计出商家id的评论标 ...
- Scala进阶之路-Scala中的枚举用法案例展示
Scala进阶之路-Scala中的枚举用法案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala中的枚举值和Java中的枚举值有点差别,不过使用起来也都差大同小异,我这 ...
- Scala进阶之路-Spark独立模式(Standalone)集群部署
Scala进阶之路-Spark独立模式(Standalone)集群部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们知道Hadoop解决了大数据的存储和计算,存储使用HDFS ...
- Scala进阶之路-Spark本地模式搭建
Scala进阶之路-Spark本地模式搭建 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spark简介 1>.Spark的产生背景 传统式的Hadoop缺点主要有以下两 ...
- Scala进阶之路-Spark底层通信小案例
Scala进阶之路-Spark底层通信小案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spark Master和worker通信过程简介 1>.Worker会向ma ...
- Scala进阶之路-Scala高级语法之隐式(implicit)详解
Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...
- Scala进阶之路-高级数据类型之集合的使用
Scala进阶之路-高级数据类型之集合的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala 的集合有三大类:序列 Seq.集 Set.映射 Map,所有的集合都扩展自 ...
- Scala进阶之路-高级数据类型之数组的使用
Scala进阶之路-高级数据类型之数组的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组的初始化方式 1>.长度不可变数组Array 注意:顾名思义,长度不可变数 ...
- Scala进阶之路-Scala的基本语法
Scala进阶之路-Scala的基本语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数式编程初体验Spark-Shell之WordCount var arr=Array( ...
随机推荐
- 20135327郭皓--Linux内核分析第九周 期中总结
Linux内核分析第九周 期中总结 一.知识概要 1. 计算机是如何工作的 存储程序计算机工作模型:冯诺依曼体系结构 X86汇编基础 会变一个简单的C程序分析其汇编指令执行过程 2. 操作系统是如何工 ...
- Web接口测试-HttpClient
要实现Web接口测试的自动化有许多方式,比如利用Jmeter.Loadrunner等测试工具都能够实现接口的自动化测试,我们也可以利用一些开源的框架来实现接口的自动化测试,比如我们现在要说的这个Htt ...
- php实现常驻进程 多进程监控
php都是通过crontabd定时脚本处理队列的,面试被问到php如何常驻进程进行处理队列,想了半天这样不知道是否是一种方式 <?php function logs(){ file_put_co ...
- Linux预处理、编译、汇编、链接和运行的过程(包括一些基本的命令)
转自Quinn0918的博客 一.预编译 1.将所有的#define删除,并展开所有的宏定义: 2.处理所有的预编译指令,例如:#if,#elif,#else,#endif; 3.处理#include ...
- FuelPHP 系列(五) ------ Security 防御
项目中难免会有 form 提交,对用户输入的所有信息进行过滤,可以避免 XSS 攻击,防止 SQL 注入. 一.设置配置信息 首先在 config.php 文件中,对 security 相关信息进行设 ...
- 软件工程_6th weeks
一.上次博客时说的UI,拖拉到现在才展示,完成了“登录,普通匹配,做题界面,做题结果”四项 功能: 二.单元测试工具 1.python单元测试工具 最近因为论文原因一直在用Python,Pytho ...
- Linux基础学习(2)--Linux系统安装
第二章——Linux系统安装 一.VMware虚拟机安装与使用 1.VMware简介: VMware是一个虚拟PC的软件,可以在现有的操作系统上虚拟出一个新的硬件环境,相当于模拟 ...
- spring学习总结(一)_Ioc基础(中)
本篇文章继续上篇文章讲解Ioc基础,这篇文章主要介绍使用spring注解配置Ioc 上篇文章主要是通过xml配置文件进行Ioc的配置.这次进行改造下,通过注解进行配置 首先先看一个简单的demo 简单 ...
- Go语言之unsafe包介绍及使用
unsafe内容介绍 type ArbitraryType int type Pointer *ArbitraryType func Sizeof(x ArbitraryType) uintptr f ...
- ansible系列5-开启加速 Ansible 执行速度的功能
SSH pipelining 是一个加速 Ansible 执行速度的简单方法.ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选 ...