Pig:运行两个聚合函数

时间:2014-07-14 18:40:36

标签: hadoop mapreduce apache-pig

我是Pig的新手,想要运行两个聚合函数,但我不知道该怎么做。我的数据包括每行一次购买交易,其中我有一个SKU(库存标识符)和客户为SKU支付的价格(价格可能会有所不同):

sku   price_paid
---   ----------
123        21.70
789        62.12
123        22.10
123        19.78
456        11.91
789        55.13

我想生成以下列表,其中包含SKU,购买SKU的次数以及为SKU支付的平均价格。列表应按降序排序。

sku      count  ave_price_paid
---  ---------  --------------
123          3           21.19
789          2           58.63 
456          1           11.91

任何帮助将不胜感激。我目前还没有走得太远:

A = LOAD 'mydata.csv' USING PigStorage(',') AS (sku:chararray, price_paid:double);
B = GROUP A BY sku;

2 个答案:

答案 0 :(得分:3)

聚合函数获取一个值并生成单个值。由于您将要操作的行李是属于GROUP BY语句创建的关系的一部分的字段,因此我首先解释一下。

GROUP BY会将具有相同值的所有记录收集到一个包中(一个包是无序的记录集合)。 关系B的记录包含2个字段:

  1. 一个键,名为group(e.i。 sku
  2. 一包收集的记录,其名称是为其分组的别名(关系名称)指定的(e.i。 A )。请注意下面你的包包如何继承"与 A 相同的架构。
  3. 让我们尝试使用DESCRIBE语句,它将显示关系的模式,例如如果你这样做:

    DESCRIBE B;
    

    输出结果为:

    B: {group: chararray,A: {(sku: chararray,price_paid: double)}}
    

    对应于上述说明。

    考虑到这一点,现在您可以执行以下语句:

    C = FOREACH B GENERATE group, COUNT(A) as (count:long), AVG(A.price_paid) as (avg:double);
    

    COUNT计算行李中的记录数,AVG平均所有作为输入提供的值,e.i。包中的元组记录的price_paid值(注意您需要访问它们的方式!

    然后执行ORDERING:

    D = ORDER C BY count desc;
    

    以下是完整的代码:

    A = LOAD 'pathOfYourFile' as (sku:chararray, price_paid:double);
    B = GROUP A BY sku;
    C = FOREACH B GENERATE group, COUNT(A) as (count:long), AVG(A.price_paid) as (avg:double);
    D = ORDER C BY count desc;
    

    有关pig内置函数的更多信息,可以查看apache参考:http://pig.apache.org/docs/r0.13.0/func.html

答案 1 :(得分:1)

这应该适合你:

C = FOREACH B GENERATE group, COUNT(A) AS count:long, AVG(A.price_paid) AS avg:double;
D = ORDER C BY count DESC;

<强>解释

让我们从您已有的代码开始:

A = LOAD 'mydata.csv' USING PigStorage(',') AS (sku:chararray, price_paid:double);
B = GROUP A BY sku;

现在我们有了关系B,它由两个字段组成:一个组名和相应的包。群组名称只是群组的名称,例如&#39; 123&#39;。该包将成为该特定组的所有行的列表。例如:

sku         bag
----       ----
123        {{123, 21.70}, {123, 22.10}, {123,19.78}}

如果您输入DESCRIBE B;,则应获得以下内容:

{group: chararray, A: {sku:chararray, price_paid:double}}

在这个模式中,A是包,并且在包中可能有很多项目中,每个包含一个sku字段和price_paid字段。

现在我们需要使用Pig强大的FOREACH...GENERATE声明:

C = FOREACH B GENERATE group, COUNT(A) AS count:long, AVG(A.price_paid) AS avg:double;

上面这一行说明对于关系B中的每一行,输出:

  1. 小组名称
  2. 小组行李的COUNT() - 整个行李中的行数。使用AS子句,将此列命名为&#39; count&#39;并使它很长。
  3. 行李中所有price_paid字段的AVG()。使用AS子句,将此列命名为“avg&#39;并使其成为双倍。
  4. 最后:

    D = ORDER C BY count DESC;
    

    这将按照&#39; count&#39;降序排列关系C.列。