如何在Pig中将一个组变成一个单元组?

时间:2013-08-31 04:48:45

标签: hadoop apache-pig

由此:

(1, {(1,2), (1,3), (1,4)} )
(2, {(2,5), (2,6), (2,7)} )

......我们怎么能产生这个?

((1,2),(1,3),(1,4))
((2,5),(2,6),(2,7))

......我们怎么能产生这个呢?

(1, 2, 3, 4)
(2, 5, 6, 7)

对于单行,我知道该怎么做。问题是我必须迭代多行并同时操作内部组。

3 个答案:

答案 0 :(得分:11)

对于您的问题,我准备了以下文件:

1,2
1,3
1,4
2,5
2,6
2,7

首先,我使用以下脚本来获取您在问题中描述的输入r3

r1 = load 'test_file' using PigStorage(',') as (a:int, b:int);
r2 = group r1 by a;
r3 = foreach r2 generate group as a, r1 as b;
describe r3;
-- r3: {a: int,b: {(a: int,b: int)}}
-- r3 is like (1, {(1,2), (1,3), (1,4)} )

如果我们想要生成以下内容,

(1, 2, 3, 4)
(2, 5, 6, 7)

我们可以使用以下脚本:

r4 = foreach r3 generate a, FLATTEN(BagToTuple(b.b));
dump r4;

对于以下内容,

((1,2),(1,3),(1,4))
((2,5),(2,6),(2,7))

我找不到任何有用的内置函数。也许你需要编写自定义的BagToTuple。以下是内置的BagToTuple源代码:http://www.grepcode.com/file/repo1.maven.org/maven2/org.apache.pig/pig/0.11.1/org/apache/pig/builtin/BagToTuple.java#BagToTuple.getOuputTupleSize%28org.apache.pig.data.DataBag%29

答案 1 :(得分:4)

为了获得:

((1,2),(1,3),(1,4))
((2,5),(2,6),(2,7))

你可以这样做:

r4 = foreach r3 {
    Tmp=foreach $1 generate (a,b);
    generate FLATTEN(BagToTuple(Tmp));
};

答案 2 :(得分:3)

没有内置方法可以将包转换为元组。这是因为包是无序的元组集,所以Pig不知道元组在转换为元组时应该设置的顺序。这意味着您必须编写UDF才能执行此操作。

我不确定你是如何创建(1, 2, 3, 4)元组的,但这是UDF的另一个很好的候选者,即使你只用BagToTuple UDF创建那个模式。

注意:除非您确切知道有多少字段,否则您可能不应该将任何内容转换为元组。

<强> myudfs.py

#!/usr/bin/python

@outputSchema('T:(T1:(a1:chararray, a2:chararray), T2:(b1:chararray, b2:chararray), T3:(c1:chararray, c2:chararray))')
def BagToTuple(B):
    return tuple(B)

def generateContent(B):
    foo = [B[0][0]] + [ t[1] for t in B ]
    return tuple(foo)

<强> myscript.pig

REGISTER 'myudfs.py' USING jython AS myudfs ; 

-- A is (1, {(1,2), (1,3), (1,4)} ) 
-- The schema is (I:int, B:{T:(I1:int, I2:int)})

B = FOREACH A GENERATE myudfs.BagToTuple(B) ;
C = FOREACH A GENERATE myudfs.generateContent(B) ;