pig基础知识总结
Pig Latin UDF语句
REGISTER 在Pig运行时环境中注册一个JAR文件
DEFINE 为UDF、流式脚本或命令规范新建别名
Pig Latin命令类型
kill 中止某个MapReduce任务
exec 在一个新的Grunt shell程序中以批处理模式运行一个脚本
run 在当前Grunt外壳程序中运行程序
quit 退出解释器
set 设置Pig选项
模式(Schema)
Pig的一个关系可以有一个关联的模式,模式为关系的字段指定名称和类型。Pig的这种模式声明方式和SQL数据库要求数据加载前必须先声明模式截然不同,Pig设计的目的是用于分析不包含数据类型信息的纯文本输入文件的。但是尽量定义模式,会让程序运行地更高效。
缺点:在查询中声明模式的方式是灵活的,但不利于模式重用。每个查询中维护重复出现的模式会很困难。处理这一问题的办法是写自己的加载函数来封装模式。
SQL数据库在加载数据时,会强制检查表模式中的约束。在pig中,如果一个值无法被强制转换为模式中申明的类型,pig会用空值null代替,显示一个空位。大数据集普遍都有被损坏的值、无效值或意料之外的值,简单的方法是过滤掉无效值:
grunt>good_records = filter recordsby temperature is not null;
另一种技巧是使用SPLIT操作把数据划分成好和坏两个关系,然后在分别进行分析:
grunt> split records intogood_records if temperature is not null,
bad_records if temperature isnull;
grunt> dump good_records;
在Pig中,不用为数据流中的每个新产生的关系声明模式。大多数情况下,Pig能够根据关系操作的输入关系的模式来确定输出结果的模式。有些操作不改变模式,如Limit。而Union会自动生成新的模式。
重新定义一个关系的模式用带as子句的FOREACH…GENERATE操作来定义输入关系的一部分或全部字段的模式
Pig的函数分为计算函数,过滤函数,加载函数和存储函数。
计算函数: AVG, COUNT, CONCAT, COUNTSTAR,DIFF, MAX, MIN, SIZE, SUM, TOKENIZE
过滤函数:IsEmpty
加载/存储函数:PigStorage,BinStorage, BinaryStorage, TextLoader, PigDump
内连接的实现:
COGROUP,inner和flatten组合使用相当于实现了内连接:
G = COGROUP A by $0 innner, B by $1inner;
H = foreach G generate flatten($1),flatten($2)
// H和join A by $0, B by $1相同
foreach…generate…
用于重新生成模式中的数据名和数据类型。默认保持原有名字,但是如果存在表达式,则无数据名,只有数据类型;而两个不兼容类型计算后,生成数据类型unknown,必须在generate
变量后使用as关键词定义别名;
#用于map查找;
.用于tuple(元组)投影;
+对于bag不适用;
下面的语句将执行不了
A= load 'foo'as (x:chararray, y:int, z:int);
B = group A by x; -- produces bag Acontaining all the records
for a given value ofx
C = foreach B generate SUM(A.y + A.z);
因为A.y
和 A.z都是bag,符号+对于bag不适用。
正确的做法如下
A= load 'foo'as (x:chararray, y:int, z:int);
A1 = foreach A generate x, y + z
as yz;
B = group A1 by x;
C = foreach B generate SUM(A1.yz);
GROUP
Group后返回一个包结构,输出两个字段:key和包含聚集记录的bag。Key的别名为group,bag名为操作表名。
group Table all 是将所有数据归为一组,名为all,{所有数据}
按多个字段group,就是按一个tuple,如group table by(a1,a2)。则返回结构中,key为“group:(a1:int,a2:int)”,而bag名为操作表名。这里key是按a1和a2组合值进行分组,实际存在的组合值,进行归并。不是先按a1,再按a2。
文档a.txt:
a 12 3 4.2 9.8
a 30 5 3.5 2.1
b 79 9 - -
a 79 9 2.6 6.2
a 12 5 7.7 5.9
a 12 3 1.4 0.2
进行pig
A =LOAD'a.txt'AS(col1:chararray, col2:int, col3:int,col4:int, col5:double, col6:double);
B =GROUPA BY(col2, col3, col4);
C =FOREACH B GENERATE group, AVG(A.col5), AVG(A.col6);
DUMPC;
((1,2,3),2.8,5.0)
((1,2,5),7.7,5.9)
((3,0,5),3.5,2.1)
((7,9,9),2.6,6.2)
按照A的第2、3、4列,对A进行分组。pig会找出所有第2、3、4列的组合,并按照升序进行排列,然后将它们与对应的包A整合起来,得到如下的数据结构:
1 |
B: {group: (col2: int,col3: int,col4: int),A: {col1: chararray,col2: int,col3: int,col4: int,col5: double,col6: double}} |
组合(1,2,3)对应了两行数据,组合(7,9,9)也对应了两行数据:
1 2 3 4 |
((1,2,3),{(a,1,2,3,4.2,9.8),(a,1,2,3,1.4,0.2)}) ((1,2,5),{(a,1,2,5,7.7,5.9)}) ((3,0,5),{(a,3,0,5,3.5,2.1)}) ((7,9,9),{(b,7,9,9,,),(a,7,9,9,2.6,6.2)}) |
Group all就是整体分成一个组,bag名为all
--double_distinct.pig
divs = load 'NYSE_dividends'as(exchange:chararray, symbol:chararray);
grpd = group divs all;
uniq = foreach grpd{
exchanges = divs.exchange;
uniq_exchanges = distinct exchanges;
symbols = divs.symbol;
uniq_symbols = distinct symbols;
generate COUNT(uniq_exchanges), COUNT(uniq_symbols);
};
注意:按all打包,作用于包grpd中每一行,是用的divs的去重,统计出一个数,放入包中。因为all包中已经不能用了
所以,要count当前表的列数,就需要,先t2=group table1 all, 然后在进行foreach t2generate count(table1.col).注意,此时的table1是bag名字,不是表名。
数列数,要先group新表,然后用用bag名字统计。
cogroup:
按多个关系中的字段进行分组。分别打包成bag,共同组成一个key的group。
按指定的共有列,分别各自组成一个bag,放到一个group组中。C = cogroup A by id, B by id;那么,id的每个值作为group的key,其后是A,B各自的bag,保存对应此key的所有记录,各自的一个bag保存对应key的所有记录,每个记录是一个元组,两个bag作为key的group。
注意:key值为null的数据都被归为同一类,这一点和group相同,和join不同。
假设有以下两个数据文件:
01 02 03 04 05 06 07 08 09 10 |
[root@localhost pig]$ cat a.txt uidk 12 3 hfd 132 99 bbN 463 231 UFD 13 10 [root@localhost pig]$ cat b.txt 908 uidk 888 345 hfd 557 28790 re 00000 |
现在我们用pig做如下操作及得到的结果为:
1 2 3 4 5 6 7 8 9 |
grunt> A = LOAD 'a.txt' AS (acol1:chararray, acol2:int, acol3:int); grunt> B = LOAD 'b.txt' AS (bcol1:int, bcol2:chararray, bcol3:int); grunt> C = COGROUP A BY acol1, B BY bcol2; grunt> DUMP C; (re,{},{(28790,re,0)}) (UFD,{(UFD,13,10)},{}) (bbN,{(bbN,463,231)},{}) (hfd,{(hfd,132,99)},{(345,hfd,557)}) (uidk,{(uidk,12,3)},{(908,uidk,888)}) |
join
join是等值连接,即自然连接。Pig只支持等值连接,非等值连接用cross。
如
daily = load 'NYSE_daily'as(exchange, symbol, date, open, high, low, close,
volume, adj_close);
divs =load 'NYSE_dividends'
as (exchange, symbol, date, dividends);
jnd =join daily by (symbol, date), divs by (symbol, date);
连接后,每个表各自的属性列,用”::”指定,如daily::symbol。非共有属性可省略。
外连接,outer join:
分 left,right,full,共3种。用null补充缺失字段。
左外连接左边的数据全部保留,其他填充null
右外连接右边的数据全部保留,其他填充null。
全外连接Full out join,两边全保留。Full关键字不可省略。
自身和自身join,要加载两次
--leftjoin.pig
daily = load 'NYSE_daily'as(exchange, symbol, date, open, high, low, close,
volume, adj_close);
divs =load 'NYSE_dividends'
as (exchange, symbol, date, dividends);
jnd =join daily by (symbol, date) left outer, divs by (symbol, date);
自身加载两次:
--selfjoin.pig
-- For each stock, find all dividends thatincreased between two dates
divs1 = load 'NYSE_dividends'
as (exchange:chararray, symbol:chararray,
date:chararray, dividends);
divs2 = load 'NYSE_dividends'
as (exchange:chararray, symbol:chararray,
date:chararray, dividends);
jnd = join divs1 by symbol, divs2 by symbol;
increased = filter jnd by divs1::date <divs2::date and
divs1::dividends <divs2::dividends;
数据多的表(或叫关系),放右边!!降低内存使用率,调高效率。
JOIN用到的key所对应的记录最多的关系(relation)排在最后,如:
D = JOIN A BY col1, B BY col1, C BY col1;
因为,pig进行join过程:map阶段标记每个记录的map,按key进行shuffle,相同值收集到一起,按map标记排序,左边输入数据先放入缓存,然后右边进来后,每一条去交叉运算,逐条比对。生成一条。
Pig函数使用:
自身udf注册才能用。引用加包名和函数
register 'your_path_to_piggybank/piggybank.jar';
divs = load 'NYSE_dividends'
as (exchange:chararray, symbol:chararray,
date:chararray, dividends:float);
backwards = foreach divsgenerate
org.apache.pig.piggybank.evaluation.string.Reverse(symbol);
define 定义别名,调用方便
--define_constructor_args.pig
register 'acme.jar';
define convertcom.acme.financial.CurrencyConverter('dollar',
'euro');
divs = load 'NYSE_dividends'
as (exchange:chararray, symbol:chararray,
date:chararray, dividends:float);
backwards = foreach divsgenerate convert(dividends);
调用python的UDF,必须声明using jython(用这个编译),并给定一个命名空间 as ball。即
Register ‘fuction.py’using jython as ball
调用的时候用ball.fuction(int param1,floatparam2)
这里,jython.jar解释器所在路径,必须提前放到类路径中,设置PIG_CLASSPATH指定。
Java函数调用:
Pig正常调用java函数,也是注册后,define别名调用,同上。如果函数有形参,在define时需要声明,叫构造函数参数,特殊的是define时不近给出形参,还要给出输出类型。多个形参在调查中?
静态java函数,pig用invoker调用。有无参数都可,但pig不支持函数返回值重载,因为每种类型有一个对应调用方法,InvokeForInt、InvokeForLong、InvokeForFloat、InvokeForDouble、InvokeForString
需要两个构造参数,一个完整包名,类名,函数名;另一个是参数。
如
托管java中的静态函数(效率较低)
--invoker.pig
define hexInvokeForString('java.lang.Integer.toHexString', 'int');
divs =load 'NYSE_daily' as (exchange, symbol, date, open, high, low,
close, volume, adj_close);
nonnull = filter divs by volume is not null;
inhex = foreach nonnull generate symbol,hex((int)volume);
如果函数的参数是一个数组,那么传递过去的是一个bag
define stdevInvokeForDouble('com.acme.Stats.stdev', 'double[]');
A = load 'input' as (id: int, dp:double);
B = group A by id;
C = foreach B generate group, stdev(A.dp);
Pig 正则表达式:
A =LOAD'a.txt'AS(col1: int, col2: chararray);
B =FILTER A BYcol2 matches '.*//.*\\.qq\\.com/.*';
DUMPB;
Matches对 col2正则匹配,使用ava格式的正则表达式匹配规则。
. 表示任意字符,* 表示字符出现任意次数;\. 对 . 进行了转义,表示匹配 . 这个字符;/ 就是表示匹配 / 这个字符。
注意,引号中转义字符 \ 需要两个才能表示, \\. 就是正则 \. ,即匹配 . 字符。所以匹配数字应该用这种写法:\d匹配数字,用\\d),B
= FILTER A BY (col matches '\\d.*');
Pig中map数量通过设置输入文件大小最小值,来限制
如:set mapred.min.split.size 2147483648; set的参数的单位是字节,所以2G=2*1024*1024*1024=2147483648。小于2G的文件将被作为一个split输入,从而一个小于2G的文件将只有一个map。假设Pig
job是一个纯map的job,输出数量会明显减少。
pig基础知识总结的更多相关文章
- 2017年5月22日 HTML基础知识(一)
一.Html 结构 1.1.HTML基本文档格式—<html> 标记 —<html>文档的头部好和主体内容 </html> 根标记 —<head> 文 ...
- .NET面试题系列[1] - .NET框架基础知识(1)
很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...
- RabbitMQ基础知识
RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...
- Java基础知识(壹)
写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...
- selenium自动化基础知识
什么是自动化测试? 自动化测试分为:功能自动化和性能自动化 功能自动化即使用计算机通过编码的方式来替代手工测试,完成一些重复性比较高的测试,解放测试人员的测试压力.同时,如果系统有不份模块更改后,只要 ...
- [SQL] SQL 基础知识梳理(一)- 数据库与 SQL
SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...
- [SQL] SQL 基础知识梳理(二) - 查询基础
SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(三) - 聚合和排序
SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...
- [SQL] SQL 基础知识梳理(四) - 数据更新
SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...
随机推荐
- [ SSH框架 ] Hibernate框架学习之二
一.Hibernate持久化类的编写规范 1.什么是持久化类 Hibernate是持久层的ORM影射框架,专注于数据的持久化工作.所谓持久化,就是将内存中的数据永久存储到关系型数据库中.那么知道了什么 ...
- jenkins + pipeline构建自动化部署
一.引言 Jenkins 2.x的精髓是Pipeline as Code,那为什么要用Pipeline呢?jenkins1.0也能实现自动化构建,但Pipeline能够将以前project中的配置信息 ...
- Zookeeper和Chubby【分布式协调系统】
前言(对于协调系统来说其客户端往往是分布式集群) 大规模分布式系统需要解决各种类型的协调需求: 当集群中有新的进程或服务器加入时,如何探测到它的加入?如何能够自动获取配置参数? 当配置信息被某个进程或 ...
- 导出数据子集:带where条件的exp导出
举个例子:用select * from all_objects创建了一张表T.想要导出object_id小于5000的所有行.(1)windows下: exp userid=cms0929/cms09 ...
- iOS支付宝,微信,银联支付集成封装调用(下)
一.越来越多的app增加第三方的功能,可能app有不同的页面但调用相同的支付方式,例如界面如下: 这两个页面都会使用第三方支付支付:(微信,支付宝,银联)如果在每一个页面都直接调用第三方支付的接口全部 ...
- Docker 工具和示例
pipework Jérôme Petazzoni 编写了一个叫 pipework 的 shell 脚本,可以帮助用户在比较复杂的场景中完成容器的连接. playground Brandon Rhod ...
- python复杂网络库networkx:绘图draw
http://blog.csdn.net/pipisorry/article/details/54291831 networkx使用matplotlib绘制函数 draw(G[, pos, ax, h ...
- iOS进阶之页面性能优化
转载:http://www.jianshu.com/p/1b5cbf155b31 前言 在软件开发领域里经常能听到这样一句话,"过早的优化是万恶之源",不要过早优化或者过度优化.我 ...
- activiti uuid主键
1.1.1. activiti默认主键生成方式 ; 下面我们看一下主键的生成策略:主键的生成策略定义在IdGenerator接口中,接口定义如下所示: public interface IdGene ...
- 分析MapReduce执行过程+统计单词数例子
MapReduce 运行的时候,会通过 Mapper 运行的任务读取 HDFS 中的数据文件,然后调用自己的方法,处理数据,最后输出.Reducer 任务会接收 Mapper 任务输出的数据,作为自己 ...