3

次のように10000行で構成される次のファイルを入力として持っています

250788965731,20090906,200937,200909,621,SUNDAY,WEEKEND,ON-NET,MORNING,OUTGOING,VOICE,25078,PAY_AS_YOU_GO_PER_SECOND_PSB,SUCCESSFUL-RELEASEDBYSERVICE,5,0,1,6.25,635-10-104-40163. 

18 列目が 10 未満で 9 列目が朝の場合、最初の列を印刷する必要がありました。次のコードを実行しました。出力が得られません。出力ファイルは空です。

public static class MyMap extends Mapper<LongWritable, Text, Text, DoubleWritable> {


    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] day=line.split(",");
        double day1=Double.parseDouble(day[17]);
        if(day[8]=="MORNING" && day1<10.0)
        {
        context.write(new Text(day[0]),new DoubleWritable(day1));
        }
    }
}
public static class MyReduce extends Reducer<Text, DoubleWritable, Text,DoubleWritable> {

    public void reduce(Text key, Iterator<DoubleWritable> values, Context context) 
      throws IOException, InterruptedException {

        String no=values.toString();
        double no1=Double.parseDouble(no);
        if(no1>10.0)
        {
        context.write(key,new DoubleWritable(no1) );
        }

    }
}

私が間違っていたことを教えてください。流れは正しいですか?

4

2 に答える 2

3

いくつかの問題が見られます。

まず、では、を比較するときに代わりに をMapper使用する必要があります。そうしないと、参照を比較するだけになり、オブジェクトの内容が同じであっても比較は失敗します。Java String のインターンが原因で成功する可能性もありますが、それが本来の意図である場合は、それに頼りすぎることは避けたいと思います。.equals()==StringString

あなたのでは、あなたReducerが何を達成したいのかわかりませんが、とにかく見つけられる間違ったことがいくつかあります。入力キーは であるIterable<DoubleWritable>ため、それを反復処理して、個々の値ごとに必要な条件を適用する必要があります。これが私があなたを書き直す方法Reducerです:

public static class MyReduce extends Reducer<Text, DoubleWritable, Text,DoubleWritable> {

    public void reduce(Text key, Iterator<DoubleWritable> values, Context context) 
      throws IOException, InterruptedException {

        for (DoubleWritable val : values) {
             if (val.get() > 10.0) {
                 context.write(key, val);
             }
        }
    }
}

しかし、全体的なロジックはあまり意味がありません。18 列目が 10 未満で 9 列目が のときに最初の列を出力するだけの場合は、マッパーの出力キーとしてMORNINGa を使用し、列 1を出力値として書き込むことができます。この場合はおそらく必要ないでしょう 。Hadoop に.NullWritableday[0]Reducerjob.setNumReduceTasks(0);

入力が 10,000 行しかない場合、Hadoop ジョブが本当に必要なのでしょうか? この小さなデータセットには、単純なシェル スクリプト (たとえば を使用awk) で十分であるように思えます。

それが役立つことを願っています!

于 2013-01-12T21:19:07.370 に答える
0
  1. データには確認したい値が既に含まれているため、これはマッパーのみの仕事だと思います。
  2. マッパーは値を発行しましたがday1 < 10.0、リデューサーは値のみを発行しました。day1 > 10.0したがって、レデューサーによって値が出力されることはありません。

したがって、レデューサーは次のようになるはずです。

String no=values.toString();
double no1=Double.parseDouble(no);
if(no1 < 10.0)
{
context.write(key,new DoubleWritable(no1) );
}

私はそれがあなたの望む出力を得るはずだと思います。

于 2013-01-13T09:10:19.603 に答える