博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Pig的输入输出及foreach,group关系操作
阅读量:6336 次
发布时间:2019-06-22

本文共 2981 字,大约阅读时间需要 9 分钟。

hot3.png

前面两篇介绍了Pig的工作以及简单的程序逻辑,从这篇开始,不再只是统计词频这样的例子了。我会相对的举出一些特殊场景加以说明。

需要说的是我也是一个Pig初学者,之前学习了一些Hadoop,在实际中还没有用武之地,自己觉得它(Hadoop)是个好东西,但是一直没有机会加以实用。自己文笔有限,写作经验也很有限,但是还是很愿意和大家分享。实在是心中实有千言,笔下仍无一策。在加上坐在电脑前面,思绪总数跑得自己都不容易控制。还希望有识之士共同学习,共同进步。

加载

任何程序都是有输入和输出的,否则它只是靠程序员录入的那一点数据怎么也只是算一个测试Demo,不能称为语言。Pig是一种流式的语言,数据流的第一步就是要加载数据,指定输入,在Pig Latin是通过Load完成的。Load默认是使用PigStorage加载存放在HDFS或者本地硬盘上的文件(以local运行),并且它默认是使用Tab分割的文件。
实际情况下,很多语言,如中文他们并不是用Tab作为分隔符分隔文本文件的,也很可能加载数据并不是从文件系统。因此可以用using句式指定加载函数。

inputs = load ‘file.txt’ using PigStorage(',');
上面的代码是加载以逗号分隔的文本文件数据,当然也可以从HBase加载数据。如:
inputs = load 'data' using HBaseStorage();
当然Pig还提供很多加载函数,也可以自定义加载数据的函数。

load语句应该使用as给加载的数据指定句式,它可以给数据加上模式(简单类型,Map, Tuple, Bar等)。如:

inputs = load 'cou.txt' using PigStorage(',') as (nameString:chararray, num1:int, num2:int);
Pig的load当指定从文件系统加载数据被指定的是文件夹时,Pig会遍历该文件夹下所有的文件并把他们作为输入。

PigStorage和TextLoader是两个内置的操作文件系统的加载函数。

存储

当数据处理完成,需要把运行的结果打印或者存储在某个地方。Pig提供了store语句把数据写入其他系统。如:

store results into ‘result.txt’ using PigStorage(',');
他会把结果集按照逗号分隔,写到文件里。还可以使用下面的代码把结果存储到HBase:
store results into ‘output’ using HBaseStorage();
输出

这个我们已经使用过了,那就是dump语句,他会把结果原样打印到控制台。方便调试和阅读。

dump result;
Pig的关系操作可以让我们把数据进行排序,分组,链接,过滤等操作。下面我详细解释下前面已经用过的foreach和group操作。

foreach

foreach语句接受一组表达式,然后在管道中把他们应用到每一条记录中。他会产生新的数据集。大家可以把它想象为多数编程语言提供的foreach语句一样,也就是遍历的处理每一条结果。如:

A = load 'file' as (id, name, age, gender ...);B = foreach A generate id, name;
如上面的例子,B相当于有了A中的两个字段组成的数据集了。当然如果A有很多个字段,我们不想要一一的写出来,我们可以仅写一个区间。如:
B = foreach A generate id - gender;B = foreach A genderate $0 - $3;B = foreach A genderate ..gender;B = foreach A genderate id..gender;
上面的结果基本都一样的,但是Pig只有在0.9开始才支持..的链接方式。熟悉Python的应该很容易的懂这个。

前面没有说过的是,Pig Latin中Tuple无论有没有模式,都可以用$加上下标来引用列。

Group

Pig中的Group和SQL中的Group类似,也产生类似的结果。这个应该不难理解。

inputs = load 'data' as (userId, friendId);grpd = group inputs by userId;dump grpd;
如上面的Group的简单实例,在会以每个用户的ID,统计该用户朋友的集合。我构造少量数据,检验一下结果。如,我构造了这样的数据,并命名文件为friend.txt
zhenqin,YangYanyangyan,Haozizhenqin,Haozizhenqin,Agouyangyan,AMaohaozi,Yangyan
不过上面的load应该这么写: inputs = load 'friend.txt' using PigStorage(',')  as (userId, friendId);

运行完成结果如:

(haozi,{(haozi,Yangyan)})(yangyan,{(yangyan,Haozi),(yangyan,AMao)})(zhenqin,{(zhenqin,YangYan),(zhenqin,Haozi),(zhenqin,Agou)})
上面,相同ID的确实聚集到一起了。如果我们要得到每个ID的朋友的ID,我们应该这么做。完整的程序:
inputs = load 'friend.txt' using PigStorage(',')  as (userId, friendId);grpd = group inputs by userId;rs = foreach grpd generate group, $1.$1;dump rs;
输出:
(haozi,{(Yangyan)})(yangyan,{(Haozi),(AMao)})(zhenqin,{(YangYan),(Haozi),(Agou)})
当然,group也支持2个以上的键进行操作,具体都大致类似,我不再举例。

Pig的Group有个遗留的问题,就是Group后groupid的别名,内定为group,如上面的语句,foreach grpd generate group, $1.$1;中的group它并不是一个group操作,而是在引用Group后分组的键名。

Group会出发一个Reduce操作,分组就意味着收集所有键中都包含相同值的记录,如果一个流处于Map阶段,那么它会立即进行shuffle,然后在进行Reduce。如果正处于Reduce,那么它还会经历一个Map-Shuffle-Reduce。

上面的程序如果要统计每个user的朋友的个数,只需要把第三行改为:

rs = foreach grpd generate group, COUNT($1.$1);
即可。这和统计词频一个道理,我不做演示。上面我用了$1.$1,如果你仔细看了这边文章, 仔细想想还应该有其他写法的。

转载于:https://my.oschina.net/zhzhenqin/blog/124277

你可能感兴趣的文章
最佳6款用于移动网站开发的 jQuery 图片滑块插件
查看>>
C++ String
查看>>
获取系统托盘图标的坐标及文本
查看>>
log4j Test
查看>>
HDU 1255 覆盖的面积(矩形面积交)
查看>>
SQL数据库无法附加,提示 MDF" 已压缩,但未驻留在只读数据库或文件组中。必须将此文件解压缩。...
查看>>
第二十一章流 3用cin输入
查看>>
在workflow中,无法为实例 ID“...”传递接口类型“...”上的事件“...” 问题的解决方法。...
查看>>
获取SQL数据库中的数据库名、所有表名、所有字段名、列描述
查看>>
Orchard 视频资料
查看>>
简述:预处理、编译、汇编、链接
查看>>
调试网页PAIP HTML的调试与分析工具
查看>>
路径工程OpenCV依赖文件路径自动添加方法
查看>>
玩转SSRS第七篇---报表订阅
查看>>
WinCE API
查看>>
SQL语言基础
查看>>
对事件处理的错误使用
查看>>
最大熵模型(二)朗格朗日函数
查看>>
html img Src base64 图片显示
查看>>
[Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction...
查看>>