从包中选择随机元组

时间:2013-01-30 12:43:09

标签: apache-pig

是否有可能(有效地)从猪的袋中选择一个随机元组? 我可以拿一个包的第一个结果(因为它是无序的),但在我的情况下,我需要一个适当的随机选择。 一个(非效率)解决方案是计算包中的元组数,在该范围内取一个随机数,循环通过包,并在迭代次数与我的随机数匹配时停止。有谁知道更快/更好的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以在嵌套的FOREACH语句中使用RANDOM(),ORDER和LIMIT来选择一个具有最小随机数的元素:

inpt = load 'group.txt' as (id:int, c1:bytearray, c2:bytearray);
groups = group inpt by id;
randoms = foreach groups {
    rnds = foreach inpt generate *, RANDOM() as rnd; -- assign random number to each row in the bag
    ordered_rnds = order rnds by rnd;
    one_tuple = limit ordered_rnds 1; -- select tuple with the smallest random number
    generate group as id, one_tuple;
};

转储randoms;

<强> INPUT:

1   a   r
1   a   t
1   b   r
1   b   4
1   e   4
1   h   4
1   k   t
2   k   k
2   j   j
3   a   r
3   e   l
3   j   l
4   a   r
4   b   t
4   b   g
4   h   b
4   j   d
5   h   k

<强>输出:

(1,{(1,b,r,0.05172709255901231)})
(2,{(2,k,k,0.14351660053632986)})
(3,{(3,e,l,0.0854104195792681)})
(4,{(4,h,b,8.906013598960483E-4)})
(5,{(5,h,k,0.6219490873384448)})

如果你运行“dump randoms;”多次,每次运行都应得到不同的结果。

编写UDF可能会提供更好的性能,因为您无需在包中随机进行二次排序。

答案 1 :(得分:0)

我需要自己做这件事,并且惊奇地发现一个非常简单的答案似乎有效,可以得到大约10%的别名A:

B = RANDOM()&lt;过滤器A 0.1