假设我有玩家ID游戏。每个id可以有多个角色名称(playerNames),我们每个名称都有一个分数。我想计算每个玩家名称的所有得分,并计算每个玩家每个玩家名称的百分比。
所以,例如:
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吗?或者,有没有一种方法可以迭代元组包并将百分数增加到所有这些而不会使数据变平?
答案 0 :(得分:1)
不,如果没有2 GROUP
,你就无法做到这一点,原因比猪只更为根本:
话虽如此,如果玩家的playerName
s的数量很小,我会写一个UDF,它拿一袋玩家得分并输出一个每玩家名称得分的包,因为每个{{ 1}}将生成一个reducer,这个过程变得非常慢。拿着袋子的UDF也必须做那两个线性通过,但是如果袋子足够小,它就没关系了,它肯定比创建另一个减速器快一个数量级。