3

サンプルにタイムスタンプを付け、Pig を使用して処理しています。毎日、サンプルの最小値とその最小値の時間を見つけたいです。したがって、最小値のサンプルを含むレコードを選択する必要があります。

簡単にするために、以下では時間を 2 つのフィールドで表します。1 つ目は日で、2 つ目はその日の「時間」です。

1,1,4.5
1,2,3.4
1,5,5.6

最小値を見つけるには、次の作業を行います。

samples = LOAD 'testdata' USING PigStorage(',') AS (day:int, time:int, samp:float);
g = GROUP samples BY day;
dailyminima = FOREACH g GENERATE group as day, MIN(samples.samp) as samp;

しかし、その後、最小値が発生した正確な時間を失いました。ネストされた式を使用できることを望みました。私は次のことを試しました:

dailyminima = FOREACH g {
  minsample = MIN(samples.samp);
  mintuple = FILTER samples BY samp == minsample;
  GENERATE group as day, mintuple.time, mintuple.samp;
};

しかし、それで私はエラーメッセージを受け取ります:

2012-11-12 12:08:40,458 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1000: 
<line 5, column 29> Invalid field reference. Referenced field [samp] does not exist in schema: .
Details at logfile: /home/hadoop/pig_1352722092997.log

minsample を定数に設定すると、文句はありません。

dailyminima = FOREACH g {
  minsample = 3.4F;
  mintuple = FILTER samples BY samp == minsample;
  GENERATE group as day, mintuple.time, mintuple.samp;
};

実際、賢明な結果が得られます。

(1,{(2)},{(3.4)})

これを書いている間、私は別のJOINを使用することを考えました:

dailyminima = FOREACH g GENERATE group as day, MIN(samples.samp) as minsamp;
dailyminima = JOIN samples BY (day, samp), dailyminima BY (day, minsamp);

これは機能しますが、(実際の場合) 1 日の値を検索するのではなく、2 つの大きなデータ セットを結合することになり、健全とは言えません。

実際のケースでは、実際に最大時間と最小時間、および関連する時間を見つけたいと思っています。ネストされた式のアプローチにより、両方を同時に実行できるようになることを願っていました。

これにアプローチする方法の提案をいただければ幸いです。

4

2 に答える 2

3

別のSO質問へのリンクを提供してくれたalexeipabに感謝します。

1つの実用的な解決策(最小値と最大値の両方と関連する時間を見つける)は次のとおりです。

dailyminima = FOREACH g {
  minsamples = ORDER samples BY samp;
  minsample = LIMIT minsamples 1;
  maxsamples = ORDER samples BY samp DESC;
  maxsample = LIMIT maxsamples 1;
  GENERATE group as day, FLATTEN(minsample), FLATTEN(maxsample);
};
于 2012-11-12T16:24:21.427 に答える
0

リレーション全体をソートせず、(潜在的な) 最小値のみをメモリに保持するという利点があるもう 1 つの方法は、PiggyBank ExtremalTupleByNthField を使用することです。この UDF はアキュムレータと代数を実装しており、非常に効率的です。

コードは次のようになります。

DEFINE TupleByNthField org.apache.pig.piggybank.evaluation.ExtremalTupleByNthField('3', 'min');

samples = LOAD 'testdata' USING PigStorage(',') AS (day:int, time:int, samp:float);

g = GROUP samples BY day;   

bagged = FOREACH g GENERATE TupleByNthField(samples);

flattened = FOREACH bagged GENERATE FLATTEN($0);

min_result = FOREACH flattened GENERATE $1 .. ;

sampフィールドに基づいてソートしているという事実は、最初のパラメーターとして3を渡すことによって DEFINE ステートメントで定義されていることに注意してください。

于 2016-01-24T13:18:35.547 に答える