web-dev-qa-db-ja.com

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)

単一行の場合、方法を知っています。問題は、多くの行を反復処理し、同時に内部グループを操作する必要がある場合です。

8
user2730009

あなたの質問のために、私は次のファイルを用意しました:

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

11
zsxwing

を手に入れるために :

((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));
};
4
Samoht-Sann

バッグをタプルに変換する組み込みの方法はありません。これは、バッグがタプルの順序付けされていないセットであるため、Pigがタプルに変換されるときにタプルがどの順序に設定されるべきかを認識できないためです。つまり、これを行うにはUDFを作成する必要があります。

(1, 2, 3, 4)タプルをどのように作成するかはわかりませんが、BagToTuple UDFだけでスキーマを作成できたとしても、これは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) ;
3
mr2ert