如何在pig中动态获取组内前n个百分比的记录

rryofs0p  于 2021-06-03  发布在  Hadoop
关注(0)|答案(2)|浏览(334)

我有一个问题,我不知道如何解决在Pig。我有一个关于hadoop的数据集(大约400万条记录),其中包含按产品类别划分的产品标题。每个标题都有它在网页上出现的次数,以及单击它转到产品详细信息页的次数。产品类别中标题的数量可能会有所不同。
样本数据-
电子游戏|光环4 | 5400 | 25
电子游戏| forza motorsport 4限量珍藏版| 6000 | 10
电子游戏|奇迹终极联盟| 2000 | 55
相机和照片|用于gopro hd的pro steadicam | 12000 | 250
照相机和照片| hero gopro motorsports 1080p宽高清5mp Helm 照相机| 10000 | 125
我想根据第3列(在网页上的出现)获得每个产品类别中前n%的记录。但是,n%必须根据类别的权重/重要性而变化。对于电子游戏,我想获得前15%的记录;对于camera&photo,我想得到前5%的值,等等。有没有办法在pig中的嵌套foreach代码块中动态设置limit子句中的%或整数值? PRODUCT_DATA = LOAD '<PRODUCT FILE PATH>' USING PigStorage('|') AS (categ_name:chararray, product_titl:chararray, impression_cnt:long, click_through_cnt:long); GRP_PROD_DATA = GROUP PRODUCT_DATA BY categ_name; TOP_PROD_LIST = FOREACH GRP_PROD_DATA {SORTED_TOP_PROD = ORDER PRODUCT_DATA BY impression_cnt DESC; SAMPLED_DATA = LIMIT SORTED_TOP_PROD <CATEGORY % OR INTEGER VALUE>; GENERATE flatten(SAMPLED_DATA); }STORE TOP_PROD_TITLE_LIST INTO '<SOME PATH>' USING PigStorage('|'); 如何动态(按类别)设置给定组的%或整数值?我曾想过使用宏,但不能从嵌套的foreach块中调用宏。我是否可以编写一个以category name为参数的自定义项,并输出%或整数值,然后通过限制操作调用此自定义项? SAMPLED_DATA = LIMIT SORTED_TOP_PROD categLimitVal(categ_name); 有什么建议吗?我使用的是pig的0.10版本。

nx7onnlm

nx7onnlm1#

像这样的办法也许行得通。但是,我从来没有必要在pigMap中查找变量键,而另一个问题没有答案,因此您需要进行一些尝试和错误操作以使其正常工作:

--Load your dynamic percentages as a map
A = LOAD 'percentages' AS (categ_name:chararray, perc:float);
PERCENTAGES = FOREACH A GENERATE TOMAP(categ_name, perc);

PRODUCT_DATA = LOAD ...;
GRP_PROD_DATA = GROUP PRODUCT_DATA BY categ_name;

--Count the elements per group; needed to calculate pecentages
C = FOREACH GRP_PROD_DATA generate FLATTEN(group) AS categ_name, COUNT(*) as count;
c_MAP = FOREACH C GENERATE TOMAP(categ_name, count);

TOP_PROD_LIST = FOREACH GRP_PROD_DATA {
    SORTED_TOP_PROD = ORDER PRODUCT_DATA BY impression_cnt DESC;
    SAMPLED_DATA = LIMIT SORTED_TOP_PROD (C_MAP#group * PERCENTAGES#group);
    GENERATE flatten(SAMPLED_DATA);
}

你也可以试着用Pig的 TOP 函数而不是 ORDER + LIMIT .

dfty9e19

dfty9e192#

我想我用一种稍微不同的方法解决了这个问题。我不确定它有多优化,也许有更好的方法来组织/优化脚本。基本上,如果我把每个类别的产品名称 ASCRANK <= SAMPLE LIMIT 然后我可以模拟动态采样。这个 SAMPLE LIMIT 只不过是 COUNT 每个类别的标题数量* PERCENT WEIGHT 按类别定义。至 RANK 元组,我利用linkedin的datafu开源jar提供 ENUMERATE 自定义项。
再说一次,如果有人对改进/更好地组织代码有什么建议,我洗耳恭听:)谢谢你的输入cabad,它真的很有帮助!
脚本:

REGISTER '/tmp/udf/datafu-1.0.0.jar';
define Enumerate datafu.pig.bags.Enumerate('1');
set default_parallel 10;

LKP_DATA = LOAD '/tmp/lkp.dat' USING PigStorage('|') AS (categ_name:chararray, perc:float);
PRODUCT_DATA = LOAD '/tmp/meta.dat' USING PigStorage('|') AS (categ_name:chararray, product_titl:chararray, impression_cnt:long, click_through_cnt:long);

GRP_PROD_DATA = GROUP PRODUCT_DATA BY categ_name;

CATEG_COUNT = FOREACH GRP_PROD_DATA generate FLATTEN(group) AS categ_name, COUNT(PRODUCT_DATA) as cnt;

CATEG_JOINED = JOIN CATEG_COUNT BY categ_name, LKP_DATA BY categ_name USING 'replicated';

CATEG_PERCENT = FOREACH CATEG_JOINED GENERATE CATEG_COUNT::categ_name AS categ_name, CATEG_COUNT::cnt AS record_cnt, LKP_DATA::perc AS  percentage;

PRCNT_PROD_DATA = JOIN PRODUCT_DATA BY categ_name, CATEG_PERCENT BY categ_name;

PRCNT_PROD_DATA = FOREACH PRCNT_PROD_DATA GENERATE PRODUCT_DATA::categ_name AS categ_name, PRODUCT_DATA::product_titl AS product_titl, PRODUCT_DATA::impression_cnt AS impression_cnt, PRODUCT_DATA::click_through_cnt AS click_through_cnt,  CATEG_PERCENT::record_cnt*CATEG_PERCENT::percentage AS sample_size;

GRP_PRCNT_PROD_DATA = GROUP PRCNT_PROD_DATA BY categ_name;

ORDRD_PROD_LIST = FOREACH GRP_PRCNT_PROD_DATA {
                             SORTED_TOP_PROD = ORDER PRCNT_PROD_DATA BY impression_cnt DESC;
                             GENERATE flatten(SORTED_TOP_PROD);
                          }

GRP_PROD_LIST = GROUP ORDRD_PROD_LIST BY categ_name;

GRP_PRCNT_PROD_DATA = FOREACH GRP_PROD_LIST GENERATE flatten(Enumerate(ORDRD_PROD_LIST)) AS (categ_name, product_titl, impression_cnt, click_through_cnt,  sample_size, rnk);

SAMPLED_DATA = FILTER GRP_PRCNT_PROD_DATA BY rnk <= sample_size;

SAMPLED_DATA = FOREACH SAMPLED_DATA GENERATE categ_name, product_titl, impression_cnt, click_through_cnt, rnk;

DUMP SAMPLED_DATA;

相关问题