2013-04-03 54 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