我找不到解决这个看似简单的问题的方法。
我有一张table,看起来像:
(USA, "big",somevalue1)
(USA, "rich",somevalue2)
(RU, "big",somevalue3)
(BR, "rich",somevalue4)
(BR, "rich",somevalue5)
作为我想要的输出
(USA, "big",somevalue1)
(USA, "rich",somevalue2)
(RU, "big",somevalue3)
(RU, "rich",0)
(BR, "rich",somevalue4)
(BR, "rich",somevalue5)
(BR, "big",0)
i、 e添加行,以便每个国家共享关于第二列的相同“信息”,即使这意味着填充零未知值。
编辑
这是我想出的解决办法
USA "big" 1
USA "rich" 2
RU "big" 3
BR "rich" 4
BR "rich" 5
(输入example.txt)
A = LOAD 'example.txt' USING PigStorage('\t') AS (cty: chararray, prop:chararray, value: int);
B = FOREACH A GENERATE cty;
B = DISTINCT B;
C = FOREACH A GENERATE prop;
C = DISTINCT C;
D = CROSS B, C;
X = JOIN D BY (cty,prop) LEFT, A BY (cty,prop) using 'replicated';
K = FOREACH X GENERATE
B::cty AS cty,
C::prop AS prop,
(value is NULL ? 0 : value);
DUMP K;
如预期:
(USA,"rich",2)
(USA,"big",1)
(RU,"rich",0)
(RU,"big",3)
(BR,"rich",4)
(BR,"rich",5)
(BR,"big",0)
1条答案
按热度按时间4ngedf3f1#
我相信最简单的方法是按第一个字段分组,然后foreach group,将相关的包发送到您自己的自定义项中,该自定义项将遍历包中的元组,并在需要时返回一个新包,其中包含现有元组+默认元组。
为了为第二个字段(“实用程序包”)创建所需值的列表,可以使用distinct和group by all。
以下是脚本的外观:
自定义自定义项应获得2个参数:
带原始模式的包:{(country:chararray,f2:字符,somevalue:chararray)}
带模式的包:{(f2:chararray)}
例如:{(大),(富),(孤独)}
为了消除元组而只留下值,您可以稍微玩一下这个包。
关于您提出的解决方案,它是好的,但是由于交叉和连接操作的使用,它的效率不是很高,这会导致额外的mapreduce作业。
在本系列中,您可以了解何时避免在pig中使用cross:http://blog.mortardata.com/post/74952451884/why-did-the-pig-cross-the-join-part-4
希望能有帮助。