PIG 过滤掉列数不正确的行
PIG filter out rows with improper number of columns
我在 a:
中加载了简单的数据
dump a
ahoeh,1,e32
hello,2,10
ho,3
我需要过滤掉所有行数 columns/fields 不同于 3 的行。该怎么做?
换句话说,结果应该是:
dump results
ahoeh,1,e32
hello,2,10
我知道应该有一个 FILTER 内置函数。但是我不知道应该定义什么条件(列数=3)。
谢谢!
你能试试这个吗?
输入
ahoeh,1,e32
hello,2,10
ho,3
3,te,0
aa,3,b
y,h,3
3,3,3
3,3,3,1,2,3,3,,,,,,4,44,6
PigScript1:
A = LOAD 'input' AS (line:chararray);
B = FOREACH A GENERATE FLATTEN(STRSPLIT(line,','));
C = FOREACH B GENERATE COUNT(TOBAG(*)),[=11=]..;
D = FILTER C BY [=11=]==3;
E = FOREACH D GENERATE ..;
DUMP E;
PigScript2:
A = LOAD 'input' USING PigStorage(',');
B = FOREACH A GENERATE COUNT(TOBAG(*)),[=12=]..;
C = FILTER B BY (int)[=12=]==3;
D = FOREACH C GENERATE ..;
DUMP D;
输出:
(ahoeh,1,e32)
(hello,2,10)
(3,te,0)
(aa,3,b)
(y,h,3)
(3,3,3)
我看到有两种方法可以做到这一点:
首先,您可以改写我认为的过滤器,归结为:给我所有不包含 NULL 值的行。对于很多列,写这个过滤语句比较繁琐。
其次,您可以使用 TOBAG (http://pig.apache.org/docs/r0.12.1/func.html#tobag) 将您的列转换为每行一个包,然后编写一个 UDF 来处理输入包以检查此包中的空元组和 return true 或 false 并在过滤器语句中使用它。
无论哪种方式,我认为都需要一些乏味。
(看来我没有足够的业力来评论;所以才发布为新答案。)
如果 null/empty 字符串是一个有效的字段值,则接受的答案不会像预期的那样表现;您需要使用 COUNT_STAR
而不是 COUNT
来计算架构中的 empty/null 个字段。
参见:https://pig.apache.org/docs/r0.9.1/func.html#count-star
例如,给定以下输入数据:
1,2,3
1,,3
和这个 Pig 脚本:
a = load 'input' USING PigStorage(',');
counted = foreach a generate COUNT_STAR(TOBAG(*)), [=11=]..;
filtered = filter counted by [=11=] != 3;
result = foreach filtered generate ..;
filtered
别名将包含这两行。区别在于 COUNT({(1),(),(3)})
returns 2
而 COUNT_STAR({(1),(),(3)})
returns 3
.
我在 a:
中加载了简单的数据dump a
ahoeh,1,e32
hello,2,10
ho,3
我需要过滤掉所有行数 columns/fields 不同于 3 的行。该怎么做? 换句话说,结果应该是:
dump results
ahoeh,1,e32
hello,2,10
我知道应该有一个 FILTER 内置函数。但是我不知道应该定义什么条件(列数=3)。
谢谢!
你能试试这个吗?
输入
ahoeh,1,e32
hello,2,10
ho,3
3,te,0
aa,3,b
y,h,3
3,3,3
3,3,3,1,2,3,3,,,,,,4,44,6
PigScript1:
A = LOAD 'input' AS (line:chararray);
B = FOREACH A GENERATE FLATTEN(STRSPLIT(line,','));
C = FOREACH B GENERATE COUNT(TOBAG(*)),[=11=]..;
D = FILTER C BY [=11=]==3;
E = FOREACH D GENERATE ..;
DUMP E;
PigScript2:
A = LOAD 'input' USING PigStorage(',');
B = FOREACH A GENERATE COUNT(TOBAG(*)),[=12=]..;
C = FILTER B BY (int)[=12=]==3;
D = FOREACH C GENERATE ..;
DUMP D;
输出:
(ahoeh,1,e32)
(hello,2,10)
(3,te,0)
(aa,3,b)
(y,h,3)
(3,3,3)
我看到有两种方法可以做到这一点: 首先,您可以改写我认为的过滤器,归结为:给我所有不包含 NULL 值的行。对于很多列,写这个过滤语句比较繁琐。
其次,您可以使用 TOBAG (http://pig.apache.org/docs/r0.12.1/func.html#tobag) 将您的列转换为每行一个包,然后编写一个 UDF 来处理输入包以检查此包中的空元组和 return true 或 false 并在过滤器语句中使用它。
无论哪种方式,我认为都需要一些乏味。
(看来我没有足够的业力来评论;所以才发布为新答案。)
如果 null/empty 字符串是一个有效的字段值,则接受的答案不会像预期的那样表现;您需要使用 COUNT_STAR
而不是 COUNT
来计算架构中的 empty/null 个字段。
参见:https://pig.apache.org/docs/r0.9.1/func.html#count-star
例如,给定以下输入数据:
1,2,3
1,,3
和这个 Pig 脚本:
a = load 'input' USING PigStorage(',');
counted = foreach a generate COUNT_STAR(TOBAG(*)), [=11=]..;
filtered = filter counted by [=11=] != 3;
result = foreach filtered generate ..;
filtered
别名将包含这两行。区别在于 COUNT({(1),(),(3)})
returns 2
而 COUNT_STAR({(1),(),(3)})
returns 3
.