在 Pig 中按元组分组
Group by tuple in Pig
我在这个问题上纠结了一段时间。我有一个如下所示的数据文件:
(1,N,N,5,High,H,House,d)
(1,N,N,6,High,H,House,a)
(2,N,N,10,Low,H,House,t)
(2,N,N,11,Medium,H,House,e)
我想要以下格式的输出。我可以用 Pig 实现吗???
{1,(N,N),{(5,High),(H,House),d},{(6,High),(H,House),a}}
{2,(N,N),{(10,Low),(H,House),t}{(11,Medium),(H,House),e}}
我实际上尝试按第一列对其进行分组。
datafile = LOAD '/user/zbc/xyz.txt' USING PigStorage() AS (id:int,
flag1:chararray, flag2:chararray, typcode:chararray, typ_name:chararray,
groupcode:charray, groupname:chararray, date:chararray);
collected = FOREACH datafile Generate TOBAG(gst_id, TOTUPLE(flag1,flag2),
TOBAG(TOTUPLE(typcode, typname), TOTUPLE(groupcode, groupname), date));
我不知道如何进行下一步。按 "one field and one tuple".
分组
好吧,您的方向是正确的,但是您是自己创建包而不是让 Pig 在分组时创建包。加载数据后,简化你的第二步,只创建你想要的元组,两个标志的组合:
collected = FOREACH datafile Generate id, TOTUPLE(flag1, flag2), ..;
..
告诉 Pig 从第四个(从 [=17=]
开始)开始包含,因此您不必重复整个参数列表。现在你将拥有:
(1,(N,N),5,High,H,House,d)
(1,(N,N),6,High,H,House,a)
(2,(N,N),10,Low,H,House,t)
(2,(N,N),11,Medium,H,House,e)
现在,您可以使用 group by
运算符按所需字段的任意组合进行分组,在本例中为 id
和标志元组:
desired_output = group collected by (id, );
在此之后,您可以根据需要对数据进行分组:
((1,(N,N)),{(1,(N,N),6,High,H,House,a),(1,(N,N),5,High,H,House,d)})
((2,(N,N)),{(2,(N,N),11,Medium,H,House,e),(2,(N,N),10,Low,H,House,t)})
编辑
如果你不想让你分组的字段出现在最后的包中,你可以使用嵌套的foreach将它们取出:
filtered_output = foreach desired_output {
AUX = foreach collected generate ..;
generate group, AUX;
}
输出:
((1,(N,N)),{(6,High,H,House,a),(5,High,H,House,d)})
((2,(N,N)),{(11,Medium,H,House,e),(10,Low,H,House,t)})
我在这个问题上纠结了一段时间。我有一个如下所示的数据文件:
(1,N,N,5,High,H,House,d)
(1,N,N,6,High,H,House,a)
(2,N,N,10,Low,H,House,t)
(2,N,N,11,Medium,H,House,e)
我想要以下格式的输出。我可以用 Pig 实现吗???
{1,(N,N),{(5,High),(H,House),d},{(6,High),(H,House),a}}
{2,(N,N),{(10,Low),(H,House),t}{(11,Medium),(H,House),e}}
我实际上尝试按第一列对其进行分组。
datafile = LOAD '/user/zbc/xyz.txt' USING PigStorage() AS (id:int,
flag1:chararray, flag2:chararray, typcode:chararray, typ_name:chararray,
groupcode:charray, groupname:chararray, date:chararray);
collected = FOREACH datafile Generate TOBAG(gst_id, TOTUPLE(flag1,flag2),
TOBAG(TOTUPLE(typcode, typname), TOTUPLE(groupcode, groupname), date));
我不知道如何进行下一步。按 "one field and one tuple".
分组好吧,您的方向是正确的,但是您是自己创建包而不是让 Pig 在分组时创建包。加载数据后,简化你的第二步,只创建你想要的元组,两个标志的组合:
collected = FOREACH datafile Generate id, TOTUPLE(flag1, flag2), ..;
..
告诉 Pig 从第四个(从 [=17=]
开始)开始包含,因此您不必重复整个参数列表。现在你将拥有:
(1,(N,N),5,High,H,House,d)
(1,(N,N),6,High,H,House,a)
(2,(N,N),10,Low,H,House,t)
(2,(N,N),11,Medium,H,House,e)
现在,您可以使用 group by
运算符按所需字段的任意组合进行分组,在本例中为 id
和标志元组:
desired_output = group collected by (id, );
在此之后,您可以根据需要对数据进行分组:
((1,(N,N)),{(1,(N,N),6,High,H,House,a),(1,(N,N),5,High,H,House,d)})
((2,(N,N)),{(2,(N,N),11,Medium,H,House,e),(2,(N,N),10,Low,H,House,t)})
编辑
如果你不想让你分组的字段出现在最后的包中,你可以使用嵌套的foreach将它们取出:
filtered_output = foreach desired_output {
AUX = foreach collected generate ..;
generate group, AUX;
}
输出:
((1,(N,N)),{(6,High,H,House,a),(5,High,H,House,d)})
((2,(N,N)),{(11,Medium,H,House,e),(10,Low,H,House,t)})