【问题标题】:PIG how to count a number of rows in aliasPIG如何计算别名中的行数
【发布时间】:2012-04-11 15:31:29
【问题描述】:

我做了这样的事情来计算 PIG 中别名中的行数:

logs = LOAD 'log'
logs_w_one = foreach logs generate 1 as one;
logs_group = group logs_w_one all;
logs_count = foreach logs_group generate SUM(logs_w_one.one);
dump logs_count;

这似乎效率太低了。如果有更好的方法请赐教!

【问题讨论】:

    标签: hadoop apache-pig


    【解决方案1】:

    按照其他答案和猪文档中的说明进行基本计数:

    logs = LOAD 'log';
    all_logs_in_a_bag = GROUP logs ALL;
    log_count = FOREACH all_logs_in_a_bag GENERATE COUNT(logs);
    dump log_count
    

    你说得对,计数效率低下,即使使用 pig 的内置 COUNT,因为这将使用一个 reducer。然而,我今天发现了一个加速它的方法之一是减少我们正在计算的关系的 RAM 使用率。

    换句话说,在计算关系时,我们实际上并不关心数据本身,所以让我们使用尽可能少的 RAM。您在第一次迭代 count 脚本时走在了正确的轨道上。

    logs = LOAD 'log'
    ones = FOREACH logs GENERATE 1 AS one:int;
    counter_group = GROUP ones ALL;
    log_count = FOREACH counter_group GENERATE COUNT(ones);
    dump log_count
    

    这将比以前的脚本处理更大的关系,并且应该更快。这个和你原来的脚本的主要区别是我们不需要总结任何东西。

    这与空值会影响计数的其他解决方案也没有相同的问题。这将计算所有行,无论第一列是否为空。

    【讨论】:

      【解决方案2】:

      使用 COUNT_STAR

      LOGS= LOAD 'log';
      LOGS_GROUP= GROUP LOGS ALL;
      LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT_STAR(LOGS);
      

      【讨论】:

        【解决方案3】:

        你想要的是计算关系中的所有行(Pig Latin 中的数据集)

        按照接下来的步骤,这很容易:

        logs = LOAD 'log'; --relation called logs, using PigStorage with tab as field delimiter
        logs_grouped = GROUP logs ALL;--gives a relation with one row with logs as a bag
        number = FOREACH LOGS_GROUP GENERATE COUNT_STAR(logs);--show me the number
        

        我不得不说 Kevin 的观点很重要,因为使用 COUNT 而不是 COUNT_STAR 我们将只有第一个字段不为空的行数。

        我也喜欢 Jerome 的单行语法,它更简洁,但为了便于说明,我更喜欢将其分成两部分并添加一些注释。

        总的来说我更喜欢:

        numerito = FOREACH (GROUP CARGADOS3 ALL) GENERATE COUNT_STAR(CARGADOS3);
        

        结束

        name = GROUP CARGADOS3 ALL
        number = FOREACH name GENERATE COUNT_STAR(CARGADOS3);
        

        【讨论】:

          【解决方案4】:

          这是一个经过优化的版本。 上面的所有解决方案都需要pig在计数时读取和写入完整的元组,下面的这个脚本只写'1'-s

          DEFINE row_count(inBag, name) RETURNS result {
              X = FOREACH $inBag generate 1;
              $result = FOREACH (GROUP X ALL PARALLEL 1) GENERATE '$name', COUNT(X);
          };
          

          像这样使用它

          xxx = row_count(rows, 'rows_count');
          

          【讨论】:

            【解决方案5】:

            Arnon Rotem-Gal-Oz 不久前已经回答了这个问题,但我想有些人可能会喜欢这个稍微简洁一点的版本。

            LOGS = LOAD 'log';
            LOG_COUNT = FOREACH (GROUP LOGS ALL) GENERATE COUNT(LOGS);
            

            【讨论】:

              【解决方案6】:

              小心,COUNT 你包里的第一个项目不能为空。否则,您可以使用函数COUNT_STAR 计算所有行数。

              【讨论】:

                【解决方案7】:

                COUNT 是猪的一部分 see the manual

                LOGS= LOAD 'log';
                LOGS_GROUP= GROUP LOGS ALL;
                LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT(LOGS);
                

                【讨论】:

                • 是否可以不先分组就计算别名中的行数?
                • 同样的问题。我读到GROUP x ALL 将强制在管道中进行序列化,从而可能会减慢速度。对吗?
                • 你必须先分组才能计数。根据pig.apache.org/docs/r0.15.0/func.html#count:“COUNT 需要前面的 GROUP ALL 语句用于全局计数和 GROUP BY 语句用于组计数。”
                • 如果LOGS 为空(零行)会有什么问题吗?
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2015-02-15
                • 2016-04-13
                • 1970-01-01
                • 1970-01-01
                • 2022-11-11
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多