在这个raw data我们有棒球运动员的信息,架构是:
name:chararray, team:chararray, position:bag{t:(p:chararray)}, bat:map[]
使用以下脚本,我们可以列出玩家和他们所扮演的不同位置。我们如何计算有多少玩家扮演某个特定位置? 例如。有多少玩家处于'Designated_hitter'位置?
单个位置不能在position
行李中多次出现。
Pig脚本和示例数据的输出如下所示。
--pig script
players = load 'baseball' as (name:chararray, team:chararray,position:bag{t:(p:chararray)}, bat:map[]);
pos = foreach players generate name, flatten(position) as position;
groupbyposition = group pos by position;dump groupbyposition;
--dump groupbyposition (output of one position i.e Designated_hitter)
(Designated_hitter,{(Michael Young,Designated_hitter)})
答案 0 :(得分:2)
据我所知,你已经完成了所有'咕噜咕噜'(哈!,猪笑话)的工作。它剩下要做的就是在GROUP BY
的输出上使用COUNT
。类似的东西:
groupbyposition = group pos by position ;
pos_count = FOREACH groupbyposition GENERATE group AS position, COUNT(pos) ;
注意:使用UDF可以获得更有效的解决方案。如果你关心计算某些字段,那么过滤它应该更有效率提前postion
包(这就是为什么我说UDF,我忘了你可以使用嵌套的FILTER
)。例如:
pos = FOREACH players {
-- you can also add the DISTINCT that alexeipab points out here
-- make sure to change postion in the FILTER to dist!
-- dist = DISTINCT position ;
filt = FILTER postion BY p MATCHES 'Designated_hitter|etc.' ;
GENERATE name, FLATTEN(filt) ;
}
如果您想要的任何位置都不会显示在postion
中,那么它会创建一个空包。当空袋被FLATTEN
时,该行被丢弃。这意味着你将成为FLATTEN
N个或更少元素的包(其中N是你想要的字段数)而不是7-15(并没有真正查看紧密相关的数据),以及{ {1}}将显着减少数据。
注意:我不确定这是否会明显加快(如果有的话)。此外,使用UDF预先形成嵌套的GROUP
可能会更快。
答案 1 :(得分:0)
你可以使用嵌套的DISTINCT来获取玩家列表而不是计算它。
players = load 'baseball' as (name:chararray, team:chararray,position:bag{t:(p:chararray)}, bat:map[]);
pos = foreach players generate name, flatten(position) as position;
groupbyposition = group pos by position;
pos_count = foreach groupbyposition generate {
players = DISTINCT name;
generate group, COUNT(players) as num, pos;
}