来学习几个简单的Hive函数吧!
作者 | 石晓文
转载自小小挖掘机(ID:wAIsjwj)
咳咳,今天来介绍一下几个Hive函数吧,先放一张我登哥划水的照片,希望大家也做一只自由的鱼儿,在知识的海洋里游呀游,嘻嘻!
今天我们来介绍几个Hive常用的函数吧!
1、数据介绍
首先我们产生我们的数据,使用spark sql来产生吧:
val data = Seq[(String,String)]( ("{\"userid\":\"1\",\"action\":\"0#222\"}","20180131"), ("{\"userid\":\"1\",\"action\":\"1#223\"}","20180131"), ("{\"userid\":\"1\",\"action\":\"2#224\"}","20180131"), ("{\"userid\":\"1\",\"action\":\"1#225\"}","20180131"), ("{\"userid\":\"1\",\"action\":\"2#225\"}","20180131"), ("{\"userid\":\"1\",\"action\":\"0#226\"}","20180131"), ("{\"userid\":\"1\",\"action\":\"1#227\"}","20180131"), ("{\"userid\":\"1\",\"action\":\"2#228\"}","20180131"), ("{\"userid\":\"2\",\"action\":\"0#223\"}","20180131"), ("{\"userid\":\"2\",\"action\":\"1#224\"}","20180131"), ("{\"userid\":\"2\",\"action\":\"1#225\"}","20180131"), ("{\"userid\":\"2\",\"action\":\"2#228\"}","20180131") ).toDF("info","dt").write.saveAsTable("test.sxw_testRowNumber")
为了模拟我们的hive函数,我们特地将info字段写成了一个json格式,info中有两个键值对,一个是user_id,另一个是用户的行为,行为中有两个数据,用#隔开,分别是动作的类型和动作发生的时间。我们可以这样认为,0代表百度首页,1代表进行了一次搜索的搜索结果页,2代表查看搜索结果中国年的某个详情页。从一次动作0 到 下一次动作0,我们可以认为这是用户和百度一次完整的交互,即一次session,从一次动作1到下一次动作1,可以认为是一次完整的搜索操作。另一个字段是dt,即我们的分区字段。
我们用简单的查询语句来看一下我们的数据效果:
select * from test.sxw_testRowNumber where dt=20180131
结果如下:
2、常用的Hive函数
▌2.1 get_json_object
我们使用get_json_object来解析json格式字符串里面的内容,格式如下:
get_json_object(字段名,'$.key')
这里,我们来解析info中的userid和action:
select get_json_object(info,'$.userid') as user_id, get_json_object(info,'$.action') as action from test.sxw_testRowNumber where dt=20180131
结果如下:
▌2.2 字符串替换函数
字符串替换函数格式如下:
regexp_replace(字段名, 被替换的内容, 替换为的内容)
这里我们是可以写正则表达式来替换的,比如我们想把#和数字都替换成大写字母Y:
select regexp_replace(info,'[\\d#]','Y') as info from test.sxw_testRowNumber where dt=20180131
在上面的语句中,我们用了两个\,因为这里\需要进行转义。结果为:
▌2.3 字符串切分函数
字符串切分函数split,很像我们java、python中写的那样,格式如下:
split(字段名,分割字符)
split分割后返回一个数组,我们可以用下标取出每个元素。我们把action里面的动作类型和动作时间使用split分割开,语句如下:
select get_json_object(info,'$.userid') as user_id, split(get_json_object(info,'$.action'),'#')[0] as action_type, split(get_json_object(info,'$.action'),'#')[1] as action_ts from test.sxw_testRowNumber where dt=20180131
结果如下:
▌2.4 取字串
取字串使用substring方法,格式如下:
substring(字段名,开始位置,提取长度)
这里,如果我们想吧info中前后的大括号去掉,可以使用substring,语句如下:
select substring(info,2,length(info)-2) as info from test.sxw_testRowNumber where dt=20180131
你可能会问,为什么开始位置是从2开始的而不是1,因为hive中字符串的索引是从1开始的而不是0,同时,我们谁用length方法来计算字符串的长度,结果如下:
▌2.5 有条件计数
有条件计数使用count函数结合case when then语法来实现,比如我们要计算每个用户有多少个session,语句如下:
select get_json_object(info,'$.userid') as user_id, count(case when split(get_json_object(info,'$.action'),'#')[0]=='0' then 1 else null end) as session_count from test.sxw_testRowNumber where dt=20180131 group by get_json_object(info,'$.userid')
结果如下:
3、分组排序函数
上面的几个函数都只是简单的开胃菜,接下来我们来介绍一下重头戏,分组排序函数以及它的两个衍生的函数,row_number() over的格式如下:
row_Number() OVER (partition by 分组字段 ORDER BY 排序字段 排序方式asc/desc)
简单的说,我们使用partition by后面的字段对数据进行分组,在每个组内,使用ORDER BY后面的字段进行排序,并给每条记录增加一个排序序号。比如,我们根据每个用户每条记录的发生时间对用户的行为进行排序,并添加一个序号:
select * row_number() over(partition by user_id order by action_ts asc) as tnfrom ( select get_json_object(info,'$.userid') as user_id, split(get_json_object(info,'$.action'),'#')[0] as action_type, split(get_json_object(info,'$.action'),'#')[1] as action_ts from test.sxw_testRowNumber where dt=20180131 ) as t
执行结果如下:
可以看到,我们已经成功给用户的行为添加了发生序号。
除了row_number以外,我们还有两个函数,分别是
lag(字段名,N) over(partition by 分组字段 order by 排序字段 排序方式)
lead(字段名,N) over(partition by 分组字段 order by 排序字段 排序方式)
lag括号里理由两个参数,第一个是字段名,第二个是数量N,这里的意思是,取分组排序之后比该条记录序号小N的对应记录的指定字段的值,如果字段名为ts,N为1,就是取分组排序之后上一条记录的ts值。
lead括号里理由两个参数,第一个是字段名,第二个是数量N,这里的意思是,取分组排序之后比该条记录序号大N的对应记录的对应字段的值,如果字段名为ts,N为1,就是取分组排序之后下一条记录的ts值。
比如,我们用lag和lead分别记录用户上一次行为和下一次行为的发生时间,语句如下:
select *, row_number() over(partition by user_id order by action_ts asc) as tn, lag(action_ts,1) over(partition by user_id order by action_ts asc) as prev_ts, lead(action_ts,1) over(partition by user_id order by action_ts asc) as next_tsfrom ( select get_json_object(info,'$.userid') as user_id, split(get_json_object(info,'$.action'),'#')[0] as action_type, split(get_json_object(info,'$.action'),'#')[1] as action_ts from test.sxw_testRowNumber where dt=20180131 ) as t
结果如下:
接下来,我们想实现下面的功能:给每条记录添加一列,该列代表此次session的开始时间。
前面我们介绍过,我们这里认为一次session是从一个action_type为0开始,到下一次action_type为0结束,也就是说,我们这里的数据有三个session,前5条记录是一个session,这五条记录的新列的值应给为222,同理,中间三条记录的新列的值应改为226,而最后四条记录的值应为223,那么如何实现这个功能呢,这就需要我们的lag和lead函数啦。
语句如下:
select t2.user_id, t2.action_type, t2.action_ts, t1.action_ts as session_tsfrom( select *, lead(action_ts,1) over(partition by user_id order by action_ts asc) as next_tsfrom ( select get_json_object(info,'$.userid') as user_id, split(get_json_object(info,'$.action'),'#')[0] as action_type, split(get_json_object(info,'$.action'),'#')[1] as action_ts from test.sxw_testRowNumber where dt=20180131 and split(get_json_object(info,'$.action'),'#')[0] == '0' ) as t ) t1
inner join
( select get_json_object(info,'$.userid') as user_id, split(get_json_object(info,'$.action'),'#')[0] as action_type, split(get_json_object(info,'$.action'),'#')[1] as action_ts from test.sxw_testRowNumber where dt=20180131 ) t2
on t1.user_id = t2.user_id
where
( t2.action_ts >= t1.action_ts and t2.action_ts < t1.next_ts
)or ( t2.action_ts >= t1.action_ts and t1.next_ts is null )
我们来一步步剖析一下该过程的实现,首先,我们在子查询中实现了两个表的内链接。第一个子查询查询出所有session开始的action_ts以及它对应的下一个session开始的action_ts,使用lead实现:
select *, lead(action_ts,1) over(partition by user_id order by action_ts asc) as next_tsfrom ( select get_json_object(info,'$.userid') as user_id, split(get_json_object(info,'$.action'),'#')[0] as action_type, split(get_json_object(info,'$.action'),'#')[1] as action_ts from test.sxw_testRowNumber where dt=20180131 and split(get_json_object(info,'$.action'),'#')[0] == '0' ) as t
第二个子查询,将简单的进行一下解析:
select get_json_object(info,'$.userid') as user_id, split(get_json_object(info,'$.action'),'#')[0] as action_type, split(get_json_object(info,'$.action'),'#')[1] as action_ts from test.sxw_testRowNumber where dt=20180131
随后,我们根据两个表的user_id进行内链接,但是内链接之后会多出很多数据,我们要从中取出满足条件的,这里的条件有两个,满足其一即可,即记录的ts在两个session开始的ts之间,要么就没有后一个session:
where
( t2.action_ts >= t1.action_ts and t2.action_ts < t1.next_ts
)or ( t2.action_ts >= t1.action_ts and t1.next_ts is null )
最终的结果如下:
(*本文为 AI科技大本营转载文章,转载请联系原作者)
◆
精彩推荐
◆
想跟NVIDIA专业讲师学习TensorRT吗?扫码进群,获取报名地址,群内优秀提问者可获得限量奖品(定制T恤或者技术图书,包邮哦~)
NVIDIA TensorRT是一种高性能深度学习推理优化器和运行时加速库,可以为深度学习推理应用程序提供低延时和高吞吐量。通过TensorRT,开发者可以优化神经网络模型,以高精度校对低精度,最后将模型部署到超大规模数据中心、嵌入式平台或者汽车产品平台中。
推荐阅读
不让华为收专利费?美议员提案“秀下限”
解密Kernel:为什么适用任何机器学习算法?
Python助你叠猫猫,抢618大红包!
Python异常处理,3个好习惯分享给你
不是码农,不会敲代码的她,却最懂程序员!| 人物志
一张图告诉你到底学Python还是Java!
这位博士跑赢“地震波”:提前 10 秒预警宜宾地震!
10分钟读懂什么是容器云?
第二! 他排中本聪与V神中间, 单靠文字就“打败”了敲代码的程序员!

相关文章:

OpenCV编程案例:使用轮廓函数检测连通区域
转自:http://www.aiseminar.cn/bbs/thread-617-1-1.html 此案例位于CXCORE中cvDrawContours函数介绍部分给出。此程序首先载入一个二值图像文件,然后使用函数再次二值化确认。接着使用cvFindContours找到轮廓,然后使用填充方式绘制轮廓线内部…

[译]Web Inspector开始支持CSS区域
最近,开发人员和设计师们可以在WebKit中尝试使用CSS区域特性了,我们认为是时候给他们一些开发工具了.最新版本的Chrome Canary中的web inspector现在已经支持下面这些功能: 查找文档中所有的命名流.显示每个命名流的内容和区域链.高亮页面中的CSS区域,就像是把鼠标放在web insp…

这或许是东半球分析十大排序算法最好的一篇文章
作者 | 不该相遇在秋天转载自五分钟学算法(ID:CXYxiaowu)前言本文全长 14237 字,配有 70 张图片和动画,和你一起一步步看懂排序算法的运行过程。预计阅读时间 47 分钟,强烈建议先收藏然后通过电脑端进行阅读。No.1 冒泡…

opencv使用cvFindContours提取联通域
转自:http://hi.baidu.com/irmosgarden/blog/item/8ce0174c54b307fad72afcbc.html // m_imgFeature为黑白目标图像,白色为前景,黑色为背景 // 注意此函数会修改m_imgFeature内容。若其不可更改,应另建立副本 // 1. count contou…

朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素
朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素 【下载文本PDF进行阅读】 本文我会来说说我认为架构评审中应该看的一些点,以及我写设计文档的一些心得。助你在架构评审中过五关斩六将,助你写出能让人收藏点赞的设计文档。 技…

Mail Archiving Expert电子邮件归档专家
概况作为企业往来最通用的交流工具,企业中有95%以上的文件都是通过邮件来传递与沟通,但是一旦当邮件服务罢工,影响的不仅仅是企业信息交流无法正确与及时的传达,更可能影响企业与客户之间的交易,其后果更是不堪设想&am…

C++中MessageBox的常见用法
转自:http://blog.csdn.net/qiumingbo/archive/2007/05/25/1625324.aspxMessageBox用法消息框是个很常用的控件,属性比较多,本文列出了它的一些常用方法,及指出了它的一些应用场合。1.MessageBox("这是一个最简单的消息框&am…

对标Mobileye!百度Apollo公布L4级自动驾驶纯视觉解决方案Apollo Lite
美国当地时间6月16日-20日,全球计算机视觉及模式识别领域顶级学术会议CVPR 2019(Conference on Computer Vision and Pattern Recognition)于美国长滩召开。百度Apollo在CVPR 2019公开了自动驾驶纯视觉城市道路闭环解决方案--百度Apollo Lite…
后台服务项目的白盒测试之旅
本文来自阿网易云社区作者:孙婷婷白盒测试起因17年下半年我开始介入部门新项目的服务v2版本的功能测试。刚接手项目时,感到十分头疼,首先它不像我刚接触测试时做的to C端项目,主要是页面展示操作,黑盒测试足够…

【自然框架 NatureFW】里的两种“映射”方式
自然框架里面采用了两种映射关系,一个是流行的ORM,另一是非主流的“CCM ” (我自己想的,呵呵)。 先说一下ORM。ORM是O和R的映射关系。也看到很多人写关于ORM的文章,发现好像有个误区。这个误区就是&#x…

ordfilt2函数功能说明
转自:http://www.ilovematlab.cn/thread-91331-1-1.html ordfilt2函数在MATLAB图像处理工具箱中提供了二维统计顺序滤波函数ordfilt2函数。二维统计顺序滤波是中值滤波的推广,对于给定的n个数值{al ,a2,...,an},将它们…

今晚直播写代码|英伟达工程师亲授如何加速YOLO目标检测
NVIDIA TensorRT是一种高性能深度学习推理优化器和运行时加速库,可以为深度学习推理应用程序提供低延时和高吞吐量。通过TensorRT,开发者可以优化神经网络模型,以高精度校对低精度,最后将模型部署到超大规模数据中心、嵌入式平台或…

TensorFlow Lite:TensorFlow在移动设备与嵌入式设备上的轻量级跨平台解决方案 | Google 开发者大会 2018...
Google 开发者大会 (Google Developer Days,简称 GDD) 是展示 Google 最新开发者产品和平台的全球盛会,旨在帮助你快速开发优质应用,发展和留住活跃用户群,充分利用各种工具获得更多收益。2018 Google 开发者大会于 9 月 20 日和 …

热烈庆祝“mysql 集群数据库架构成功”
坚持了两周,终于在linux下把mysql集群数据库给架起来了!下面简单说明下集群数据库原理 第一:集群数据库分MGM,NDBD,SQL 其中MGM是相当于“中央政府”,维持NDBD,SQL等服务器的之间的关系的 NDBD是数据存储的分布化&…

352万帧标注图片,1400个视频,亮风台推最大单目标跟踪数据集
CVPR 2019期间,专注于AR技术,整合软硬件的人工智能公司亮风台公开大规模单目标跟踪高质量数据集LaSOT,包含超过352万帧手工标注的图片和1400个视频,这也是目前为止最大的拥有密集标注的单目标跟踪数据集。论文《LaSOT: A High-qua…

centos7中nfs文件系统的使用
需求:file01:1.1.1.1(内网ip 172.20.103.212),file02:2.2.2.2(内网ip 172.20.103.211) 这两台机器的 /dev/mapper/myvg-mylv /data 这个盘都挂载到 video01 47.254.78.171, video02 47.254.83.81 这两台机器上即将file01和file02的/data目录都挂载到vid…

在图像变换中用最小二乘法求解仿射变换参数
设原图像为f(x,y),畸变后的图像为F(X,Y),要将F(X,Y)恢复为f(x,y),就是要找到(X,Y)坐标与(x,y)坐标的转换关系,这个转换关系称为坐标变换,表示为(x,y)T(X,Y)。 景物在成像过程中产生的扭曲,会使图像的比例失…

showModalDialog关闭子窗口,并刷新父窗口
一、用法:window.showModalDialog(url,args,dialogWidth650px;scrollno;dialogHeight250px;statusno; ); 二、关闭子窗口,并刷新父窗口 想在showModalDialog打开的窗口中提交表单且不打开新窗口 只需在打开的页面的<head>中加入<base target&qu…

cvDrawContours:在图像上绘制外部和内部轮廓
转自:http://www.aiseminar.cn/html/18/t-618.html?action-uchimage 函数cvDrawContours用于在图像上绘制外部和内部轮廓。当thickness > 0 时,绘制轮廓线;否则填充由轮廓包围的部分。 void cvDrawContours( CvArr *img, CvSeq* contour,…

Python最抢手、Go最有前途,7000位程序员揭秘2019软件开发现状
作者 | 屠敏 整理报告来源 | JetBrains转载自 CSDN(ID:CSDNnews)互联网的下半场,科技公司为面对更加严峻的竞争环境,越来越重视开源节流。而对于身处其中且撑起 IT 半边天的技术人,如今如何了?从…

main函数参数
参考:Where Does GCC Look to Find its Header Files? 命令行参数 VS 程序参数 ./a.out 1 2 3 4 5 6 1 2 3 4 5 6是程序参数,是传给a.out这个程序处理的,main里面的argv来接收 ./a.out 1 2 3 4 5 6完整的这一串才是命令行参数 代码演示 如下…

转载 load-on-startup的用法
转载于:http://www.ituring.com.cn/article/50477 Web.xml中的Servlet中的配置: <servlet><servlet-name>createBlog</servlet-name><servlet-class>com.cnblogs.CreateBlog</servlet-class><load-on-startup>0</load-on-s…

商汤62篇论文入选CVPR 2019,一览五大方向最新研究进展
(图源自视觉中国)作为与ICCV、ECCV并称为计算机视觉领域三大国际会议之一,本届CVPR大会共收到5265篇有效投稿,接收论文1300篇,接收率为25.2%。商汤科技CVPR 2019录取论文在多个领域实现突破作为国内CV领域的明星公司&a…

cvSaveImage保存图像
转自:http://blog.csdn.net/luhuillll/archive/2009/10/28/4739471.aspx opencv保存图象直接使用cvSaveImage,这个函数.但是windows位图的图象格式是RGBt格式,而opencv的图象存储格式是BGR. 这样导致保存的图象失真.在windows下查看图象好象变绿色了.所以在保存图象…

软工实践原型设计——PaperRepositories
软工实践原型设计——PaperRepositories 写在前面 本次作业链接队友(031602237吴杰婷)博客链接pdf文件地址原型设计地址(加载有点慢...)结对成员:031602237吴杰婷 & 031602636许舒玲原型设计工具:Axure RP 8PSP表格 PSP3.1Personal Software Process…

nagios+sendmail配置
以下为自己安装测试过的,如果有问题,大家一起讨论 系统环境:centos6.2 64位 最小化安装 一 安装nagios 见附件:nagios官方文档(nagios_nrpe20120929_web.pdf) 二 安装配置sendmail 我用hotmail邮箱接收nagi…

真正的博士是如何参加AAAI, ICML, ICLR等AI顶会的?
(图源自视觉中国)整理 | 一一出品 | AI科技大本营(ID:rgznai100)源于对学术的热爱,让很多人走上了博士这条求索之路,而热爱会让他们勤奋付出,勤奋让他们成为佼佼者。在刚刚过去的 ICML 大会上&a…

matlab图像滤波
转自:http://hi.baidu.com/wang%5Fpw/blog/item/36354a637ac87b48eaf8f879.html clc; clear all; Iimread(eight.tif); % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %用中值滤波,多维滤波,使用中心为-4,-8的拉普 % %拉…

2018你不得不看的国内CRM软件排行榜
2018你不得不看的国内CRM软件排行榜短短几年时间,CRM在中国的发展就已经非常迅猛,现在已经成为了管理软件增长最快的产业。在我们总结的CRM软件排行榜中,腾讯企点的CRM软件赫然摆在前列。而CRM在中国中小企业已经突破千万家,占全国…

二维物体形状识别方法比较
二维物体形状识别方法比较 摘 要 针对模式识别中二维物体的形状识别问题,以二值图像中的物体形状为主要研究对象,依次从特征提取、分类器设计两个主要层面对形状识别方法进行了全面综述,并分析了国内外研究现状,特别是近年来所取…