Pig的输入输出及foreach,group关系操作

前面两篇介绍了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,YangYan
yangyan,Haozi
zhenqin,Haozi
zhenqin,Agou
yangyan,AMao
haozi,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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值