2013-04-03 59 views
0

假设我有一个玩家ID的游戏。每个ID可以有多个角色名称(playerNames),我们对每个名称都有一个评分。我想总计每个playerName的所有分数,并计算每个玩家名称每个id的百分比分数。在猪群结果内循环通过

所以,举例来说:

 
id playerName playerScore 
01 Test  45 
01 Test2  15 
02 Joe   100 

将输出

 
id {(playerName, playerScore, percentScore)} 
01 {(Test, 45, .75), (Test2, 15, .25)} 
02 {(Joe, 100, 1.0)} 

我是这样做的:

data = LOAD 'someData.data' AS (id:int, playerName:chararray, playerScore:int); 
grouped = GROUP data BY id; 

withSummedScore = FOREACH grouped GENERATE SUM(data.playerScore) AS summedPlayerScore, FLATTEN(data); 

withPercentScore = FOREACH withSummedScore GENERATE data::id AS id, data::playerName AS playerName, (playerScore/summedPlayerScore) AS percentScore; 

percentScoreIdroup = GROUP withPercentScore By id; 

目前,我这样做有2 GROUP BY语句,我很好奇,如果他们都是必要的,或者如果有更有效的方法来做到这一点。我可以将其减少到单个GROUP BY吗?或者,有没有一种方法可以迭代一堆元组,并将percentScore添加到所有元组中,而不会压扁数据?

回答

1

不,你不能没有2 GROUP做到这一点,其原因不仅仅是猪更基本:

  1. 拿分的总数量,你需要通过玩家的分数直线传球。
  2. 然后,您需要通过玩家分数的另一个直线传球来计算分数。你可以不是这样做之前,你知道的总和。

话虽如此,如果玩家的的playerName的号码是小,我会写一个UDF是需要玩家分数的袋子和输出得分每playerName元组的包,因为每个GROUP将产生减速器和过程变得非常慢。采用这种袋子的UDF也必须进行这两种线性通过,但如果袋子足够小,则无关紧要,并且它的速度肯定比创建另一个减速器快一个数量级。

+0

这样做很有意义,谢谢TC1 – Newtang