zoukankan      html  css  js  c++  java
  • pig实战 pig常用语法总结,教你快速入门——算法篇

      本文主要来源于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数

  • 相关阅读:
    bash /root/.bashrc permission denied
    vscode 在ubuntu的terminal中下划线不显示解决方案
    基于SSH框架的考勤管理系统的设计与实现
    关于《实验一》的框架选择
    认知架构
    《软件需求》读书笔记3
    《软件需求》读书笔记1
    《软件需求》读书笔记2
    《软件方法》读书笔记2
    《软件方法》读书笔记3
  • 原文地址:https://www.cnblogs.com/uttu/p/2917438.html
Copyright © 2011-2022 走看看