本文主要来源于google资料的自我总结,对常用的pig语法即“算法”进行了总结
基础概念: relation bag tuple field data 关系(relation) = 包(bag) 一个包是一个元组(tuple)的集合,在pig中用{}扩起来表示一个包 一个元组(tuple)是若干个字段的有序集合(order set),在pig的数据结构中,用()扩起来标识一个元组 一个字段(field)是列数据(data)的标识;
和数据库的对应关系: pig database relation/bag table tuple one record field field(one volume)
但是pig中tuple的字段数是随意的,这点和数据库不同
运行模式以及注释: 1、 运行模式 a) 本地 i. pig –x local b) 集群 i. pig –x mapreduce ii. 或者pig c) 批处理命令 i. 将命令批量写入xx.pig ii. 用本地或者集群模式运行,如pig xx.pig
2、注释 a) 段落注释:/**/ b) 行注释: --
基本用法框架: a) 输入 i. A = Load ‘输入路径’ USING PigStorage(“\t”) AS (name:chararray, age:int, gpa:float); ii. 逻辑:用pig自带的PigStorage读入输入路径的数据,对每一行用”\t”分割,并用字符串类型的name、int类型的age、float类型的gpq作为每行数据的字段名 b) 中间处理 i. B = FOREACH A GENERATE name; c) 输出 i. DUMP B; --输出到控制台 ii. 或者STORE B INTO ‘输出路径’ USING PigStorage();
基本语法实例: 1、计算多维度组合下的平均值 的实际例子 需求:求文件中第2、3、4组合的第4、5列的平均值 脚本解释: A = Load '1.txt' USING PigStorage(' ') AS(col1:chararray, col2:int, col3:int, col4:int, col5:double, col6:double); 将1.txt中的每行数据用" "分割,然后安装(col1:chararray, col2:int, col3:int, col4:int, col5:double, col6:double)解析数据,并装载到每个bag/tuple/filed col1是每列的别名,如果不指定,在后面可以用$0,$n来索引,但是可读性较差
A的结构是{col1:chararray, col2:int, col3:int, col4:int, col5:double, col6:double)}
B = GROUP A BY (col2, col3, col4); 对A用col2/col3/col4的组合进行分组,然后按组将每条tuple汇集成一个bag, B的数据结构是B:{group:(col2,col3,col4),A:bag{:tuple,tuple}}
C = FOREACH B GENERATE group, AVG(col5), AVG(col6); FOREACH是遍历每个组中汇集的tuple,并对其用组合函数处理字段 C的结构是C:{group:(col2,col3,col4),double,double}
DUMP C;//单机运行打印调试信息 STORE C INTO “output”;//存储结果
2、统计行数 A = LOAD '1.txt' USING PigStorage (' ‘) AS(col1:chararray, col2:int, col3:int, col4:int, col5:double, col6:double); B = GROUP A all; C = FOREACH B GENERATE COUNT(col2); DUMP C; 注意:如果col2这一列有NULL,则这一行将不会被统计。 GROUP A all;没有by关键字。 If you want to include NULL values in the count computation, use COUNT_STAR.
3、FLATTEN 同1中的例子,但是C不同 C = FOREACH B GENERATE FLATTEN(group), AVG(col5), AVG(col6); 1中的例子得到的结果结构是(col2, col3, col4),avg1,avg2 但是对group作用FLATTEN后结构变为col2,col3,col4,avg1,avg2;可以看出FLATTEN的作用是解嵌套(un-nest)包或者元组tuple,
4、GROUP的两点说明: a)用于GROUP的key如果多于一个字段(正如本文前面的例子),则GROUP之后的数据的key是一个元组(tuple),否则它就是与用于GROUP的key相同类型的东西 b)GROUP后得到的结果是一个包或者是relation,其包含的每一个tuple中包含两个字段,第一个字段被命名为'group',第二个字段是一个包,是含有group对应值的所有tuple的set
5、把数据作为tuple来加载 语法:A = LOAD '1.txt' AS (T: tuple(col1:chararray, col2:int, col3:int,col4:int, col5:double, col6:double); 用describe A;可以查看A的结构。 注意:输入的数据必须是(xx,xx,xx...xx)的结构才能以元组的形式被加载,适用于中间结果的进一步处理
6、计算多维组合中不重复记录的条数 C = FOREACH B GENERATE (D = DISTINCT col5; group, COUNT(D)); 说明:distinct后跟一个字段即可,如果这个字段不同,则肯定不重复,而如果重复,此字段肯定相同,而且重命名D要用等号,后面跟;
7、将relation转为表量scalar
8、在pig中使用shell脚本进行辅助处理 A = LOAD ‘2.txt' AS (col1:int, col2:int, col3:int, col4:chararray, col5:int); B = STREAM A THROUGH `awk '{if($4 == "=") print $1"\t"$2"\t"$3"\t"999"\t"$5; else print $0}'`; DUMP B; 作用:将第4列中的"="换成999
9、向pig脚本传参: 语法:pig -param output_dir="/xxx" xxx.pig; 而在xxx.pig中STORE D INTO ‘$output_dir’;
10、COGROUP的作用: 对两个关系中的包,分别按制定的字段进行分组 A = LOAD '3.txt' AS (acol1:chararray, acol2:int, acol3:int); B = LOAD '4.txt' AS (bcol1:int, bcol2:chararray, bcol3:int); C = COGROUP A BY A.acol1, B BY B.bcol2; DUMP C; 结果的结构{key,{A's one tuple or null},{B's ont tuple or null}}; 按A的第一行和B的第二行的值,分别对A、B进行分组组合,如果A中的tuple含有此key则显示在结果中,如果没有则为{},B也一样
11、piggybank 自定义函数的名称为piggybank
12、UDF的构造函数会被调用多次,所以在其中做一次工作时要特别小心
13、LOAD多个目录下的数据 LOAD '/data/201{1,2}' load/data/2011 /data/2012两个目录下的数据
14、GROUP 函数不会忽略NULL值,而COUNT会
15、统计某些字段组合的种数: A = LOAD '15.txt' AS (col1:int, col2:int); B = GROUP A BY (col1, col2); C = GROUP B ALL; D = FOREACH C GENERATE COUNT(B); DUMP D; 思路:先根据需求对数据进行分组,然后对分组COUNT; 注意: a)D中COUNT的是B,因为通过C将所有的数据组为一个新的关系,只包含一个tuple,第一个字段为ALL,第二个字段是B的所有tuple组成的一个bag。 b)COUNT作用的对象必须是一个bag,所以在统计字段前,要用GROUP X ALL,将X中所有的tuple组成一个bag
16、两个整数相除,如何得到一个float A = LOAD '16.txt' AS (col1:int, col2:int); B = FOREACH A GENERATE (float)col1/col2; DUMP B; 注意先转型在计算,而不是(float)(col1/col2);
17、UNION两个数据进行统计 A = LOAD '1.txt' AS (col1:int, col2:int); B = LOAD '2.txt' AS (col3:int, col4:int); C = UNION A, B; D = GROUP C BY $0; E = FOREACH D GENERATE group, SUM(C.$1); #E = FOREACH D GENERATE FLATTEN(group), SUM(C.$1); DUMP E; 注意: UNION操作是给关系添加新的tuple,而且UNION后注意观测filed的引用方法,见结构篇 多个关系时,对列的操作要指定关系名
18、正则表达式过滤 过滤出符合*//*.qq.com/*的url A = LOAD '18.txt' AS (col1:int, col2:chararray); B = FILTER A BY col2 matches '.*//.*\\.qq\\.com/.*'; 说明:.*标识至少一个字符 而匹配.字符要进行转义\.,而在''内转义要用两个\\. ;
19、截取字符串: SUBSTRING(col1, 0, 4):0为startIndex,4为stopIndex,不包含stopIndex;
A = LOAD '19.txt' AS (dataStr:chararray, col2:chararray); B = FOREACH A GENERATE SUBSTRING(dataStr,0,4); C = DISTINCT B; DUMP C;
20、连接字符串: A = LOAD ‘20.txt' AS (col1:chararray, col2:int); B = FOEACH A GENERATE CONCAT(col1, (chararray)col2); DUMP B; 注意:连接的字段类型必须是chararray,如果不是要转型 嵌套使用:CONCAT(A,CONCAT(B,C);
21、用JOIN求两个数据集的交集&不同数据类型交集会失败 A = LOAD '211.txt' AS (a:int); B = LOAD '212.txt' AS (b:int); C = JOIN A BY a, B BY b; D = GROUP C ALL; E = FOREACH D GENERATE COUNT(C); DUMP E; JOIN后C的结构为:C:{A::a:int, B::b:int}
去重: A = LOAD '211.txt' AS (a:int); B = LOAD '212.txt' AS (b:int); C = JOIN A BY a, B BY b; uniq_C = DISTINCT(C); D = GROUP uniq_C ALL; E = FOREACH D GENERATE COUNT(C); DUMP E;
22、三目运算符使用必须使用():用来替换空值 B = FOREACH A GENERATE ((col1 is null) ? -1 : col1)
23、如何在得到计算结果后,补齐空白 A = LOAD ‘23.txt' AS (col1:int, b:tuple(col2:int, col3:int); B = FOREACH A GENERATE col1, FLATTEN(b); C = GROUP B BY B.col1; D = FOREACH C GENERATE group, SUM(B.col1) AS sum; E = FOREACH D GENERATE group, ((sum is null) ? 0 : sum); DUMP E;
24、DISTINCT操作用于去重,正因为它要把数据集合到一起,才知道哪些数据是重复的,因此,它会产生reduce过程。同时,在map阶段,它也会利用combiner来先去除一部分重复数据以加快处理速度。
25、提高Pig job的优先级:set job.priority HIGH;提高Pig job的运行速度
26、“Scalars can be only used with projections”错误和嵌套/inner FOREACH 在第一列的每种组合中,第二列为3/6的数据分别有多少条
A = LOAD ’26.txt' AS (col1:chararray, col2:int); B = GROUP A BY col1; C = FOREACH B { D = FILTER A BY col2 == 3; E = FILTER A BY col2 == 6; GENERATE group, COUNT(D), COUNT(E);}; DUMP C;
27、在grunt模式下按Ctrl+A 和 Ctrl+E 代替 HOME 和 END,就可以跳到行首和行末了
28、同一个关系进行JOIN连接必须导入两次,做连接,否则出错
29、外链接JOIN LEFT:左边的数据全量显示
A = LOAD '291.txt' AS (col1:int, col2:chararray); B = LOAD '292.txt' AS (col1:int, col2:chararray); C = JOIN A BY col1 LEFT, B BY col1; DESCRIBE C; DUMP C; 这个和数据库的左右连接和内链接一致
30、pig中支持过滤中文,但是在交互模式下不行
31、统计 tuple 中的 field 数,bag 中的 tuple 数,map 中的 key/value 组数用SIZE函数
32、字符此为null 用col is null来判断,但是不能过滤" "," " 过滤要用SIZE(xx)>0 FILTER A BY (col1 is not null AND (SIZE(col2) > 0));
33、Pig中的各operator(操作符),哪些会触发reduce过程 GROUP:由于GROUP操作会将所有具有相同key的记录收集到一起,所以数据如果正在map中处理的话,就会触发shuffle→reduce的过程。 ORDER:由于需要将所有相等的记录收集到一起(才能排序),所以ORDER会触发reduce过程。同时,除了你写的那个Pig job之外,Pig还会添加一个额外的M-R job到你的数据流程中,因为Pig需要对你的数据集做采样,以确定数据的分布情况,从而解决数据分布严重不均的情况下job效率过于低下的问题。 DISTINCT:由于需要将记录收集到一起,才能确定它们是不是重复的,因此DISTINCT会触发reduce过程。当然,DISTINCT也会利用combiner在map阶段就把重复的记录移除。 JOIN:JOIN用于求重合,由于求重合的时候,需要将具有相同key的记录收集到一起,因此,JOIN会触发reduce过程。 LIMIT:由于需要将记录收集到一起,才能统计出它返回的条数,因此,LIMIT会触发reduce过程。 COGROUP:与GROUP类似(参看本文前面的部分),因此它会触发reduce过程。 CROSS:计算两个或多个关系的叉积。
34、如何统计一个字符串中包含的指定字符数 shell 脚本 awk -F ":" '{print NF - 1}' 以:分割字符串,然后打印总的volume数
|