猪:计算分组列的出现次数

时间:2013-09-19 11:53:53

标签: hadoop apache-pig

在这个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)})

2 个答案:

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