如何计算每个单独行的特定字符串的出现次数,例如“Y”,并在此之后对该计数进行计算。对于前者如何为每个'FMID'找到'Y'的数量,并为每个FMID计算该计数?Dataset Screenshot
答案 0 :(得分:0)
您可以使用TOKENIZE内置函数将行转换为BAG,而不是在foreach中使用嵌套过滤来获取仅包含您感兴趣的单词的BAG,您可以在其上使用COUNT。见FOREACH description 例如:
inpt = load '....' as (line : string);
row_bags = foreach inpt generate line, TOKENIZE(line) as word;
cnt = foreach row_bags {
match_1 = filter word by 'Y';
match_2 = filter word by 'X';
generate line, COUNT(match_1) as count_1, COUNT(match_2) as count_2;
};
dump cnt;
使用DataFu库中的某些函数,您可以计算BAG字中每个字符串的数量。
答案 1 :(得分:0)
这是我能想到解决问题的最简单方法:
define Transpose datafu.pig.util.TransposeTupleToBag();
data = LOAD 'input' USING PigStorage(',') AS
(fmid:int, field1:chararray, field2:chararray,
field3:chararray, field4:chararray);
data2 = FOREACH data GENERATE fmid, Transpose($1..) as fields;
data2 = FOREACH data2 {
y_fields = FILTER fields BY value == 'Y';
GENERATE fmid, SIZE(y_fields) as y_cnt;
}
我不确定您正在使用的数据模式。我将假设你在Pig中有一系列由一系列元组构成的关系。我也会假设你有很多领域,每个人都很难参考。
我将逐步解释这个例子。不失一般性,我将使用下面的数据作为我的例子:
data = LOAD 'input' USING PigStorage(',') AS (fmid:int, field1:chararray, field2:chararray, field3:chararray, field4:chararray);
现在我们已经加载了数据,我们希望将每个元组转置到一个包中,因为一旦它放入包中,我们就可以更轻松地对其中的项进行计数。我们将使用DataFu库中的TransposeTupleToBag:
define Transpose datafu.pig.util.TransposeTupleToBag();
data2 = FOREACH data GENERATE fmid, Transpose($1..) as fields;
请注意,至少需要使用Pig 0.11才能使用此UDF。注意使用$ 1 ..,这在Pig中称为项目范围表达式。如果你有很多字段,这真的很方便。
如果你此时要转储data2,你会得到这个:
(1000,{(field1,N),(field2,N),(field3,N),(field4,N)})
(2000,{(field1,N),(field2,Y),(field3,N),(field4,N)})
(3000,{(field1,Y),(field2,Y),(field3,N),(field4,N)})
(4000,{(field1,Y),(field2,Y),(field3,Y),(field4,Y)})
我们所做的是从第0个元素(fmid)之后的元组中取出字段,并将它们转换成一个包,其中每个元组都有一个键和值字段。
现在我们有了一个包,我们可以做一个简单的过滤器并计算:
data2 = FOREACH data2 {
y_fields = FILTER fields BY value == 'Y';
GENERATE fmid, SIZE(y_fields) as y_cnt;
}
现在,如果你转储data2,你会得到反映元组中Y值的数量的预期计数。
(1000,0)
(2000,1)
(3000,2)
(4000,4)
以下是我的示例作为单元测试的完整源代码,您可以将其直接放入DataFu单元测试中试用:
/**
register $JAR_PATH
define Transpose datafu.pig.util.TransposeTupleToBag();
data = LOAD 'input' USING PigStorage(',') AS (fmid:int, field1:chararray, field2:chararray, field3:chararray, field4:chararray);
data2 = FOREACH data GENERATE fmid, Transpose($1..) as fields;
dump data2;
data2 = FOREACH data2 {
y_fields = FILTER fields BY value == 'Y';
GENERATE fmid, SIZE(y_fields) as y_cnt;
}
dump data2;
STORE data2 INTO 'output';
*/
@Multiline
private String example;
@Test
public void example() throws Exception
{
PigTest test = createPigTestFromString(example);
writeLinesToFile("input",
"1000,N,N,N,N",
"2000,N,Y,N,N",
"3000,Y,Y,N,N",
"4000,Y,Y,Y,Y");
test.runScript();
super.getLinesForAlias(test, "data2");
}