获取特定字符串的计数

时间:2014-01-04 20:24:08

标签: apache-pig

如何计算每个单独行的特定字符串的出现次数,例如“Y”,并在此之后对该计数进行计算。对于前者如何为每个'FMID'找到'Y'的数量,并为每个FMID计算该计数?Dataset Screenshot

2 个答案:

答案 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");
}