2

如果我有以下数据集:

c1   c2
---  ---
1    5
1    5
1    6
2    9
2    9
3    1
3    2

我想为第一列 (c1) 中的每个值返回第二列 (c2) 中出现频率最高的值。所以我希望返回的数据集如下所示,因为对于 c1=1,值“5”出现两次,值“6”只出现一次,而对于 c1=2,值“9”出现两次,没有出现其他值:

1    5
2    9
3    1

我遇到问题的情况是出现的次数相等(在这种情况下,c1=3。)在 c2 中出现的值数量相等的情况下(c1=3),我只想要第一次出现返回。

任何想法都会有所帮助。

4

2 回答 2

2

假设您在 A 上有 c1 和 c2 :

B = GROUP A BY (c1, c2)
C = FOREACH B GENERATE GROUP, COUNT(A) as num;

D = GROUP C BY GROUP.c1
E = FOREACH D {
    SA = ORDER C BY num DESC;
    SB = LIMIT SA 1;
    GENERATE FLATTEN(SB.group);
}

应该可以解决您的问题。(虽然我在记事本中写过,你应该通过描述/说明检查是否需要任何扁平化)

于 2012-05-08T12:44:56.537 回答
1

对于像我这样的语言新手并试图理解上面代码中发生的事情的每个人,我的评论版本(添加了描述和转储输出):

数据样本('sample_data/test_limiting.pig'):

1|5
1|5
1|6
2|9
2|9
3|1
3|2

还有猪脚本本身:

A = LOAD 'sample_data/test_limiting.pig' USING PigStorage('|') AS (c1:int, c2:int);
----
-- A: {c1: int,c2: int}
----
-- (1,5)
-- (1,5)
-- (1,6)
-- (2,9)
-- (2,9)
-- (3,1)
-- (3,2)


B = GROUP A BY (c1, c2);
----
-- B: {group: (c1: int,c2: int),A: {(c1: int,c2: int)}}
----
-- ((1,5),{(1,5),(1,5)})
-- ((1,6),{(1,6)})
-- ((2,9),{(2,9),(2,9)})
-- ((3,1),{(3,1)})
-- ((3,2),{(3,2)})


C = FOREACH B GENERATE group, COUNT(A) as num;
----
-- C: {group: (c1: int,c2: int),num: long}
----
-- ((1,5),2)
-- ((1,6),1)
-- ((2,9),2)
-- ((3,1),1)
-- ((3,2),1)


D = GROUP C BY group.c1;
----
-- D: {group: int,C: {(group: (c1: int,c2: int),num: long)}}
----
-- (1,{((1,5),2),((1,6),1)})
-- (2,{((2,9),2)})
-- (3,{((3,1),1),((3,2),1)})


E = FOREACH D {
    SA = ORDER C BY num DESC;
    SB = LIMIT SA 1;
    GENERATE FLATTEN(SB.group);
}
----
-- E: {null::group: (c1: int,c2: int)}
----
-- ((1,5))
-- ((2,9))
-- ((3,1))

顺便说一句,我需要用小写字母写参考“组”,因为它被大写变体轰炸了。可能因为版本不同,不知道。

于 2013-08-19T09:57:49.810 回答