【问题标题】:MapReduce to calculate sum of tab separated input valuesMapReduce 计算制表符分隔输入值的总和
【发布时间】:2016-12-07 05:47:06
【问题描述】:

我正在尝试使用 MapReduce 来查找由标签分隔的制表符分隔输入的总和。数据是这样的

1     5.0    4.0   6.0
2     2.0    1.0   3.0
1     3.0    4.0   8.0

第一列是类标签,所以我期待一个按类标签分类的输出。对于这种情况,输出将是

label 1: 30.0
label 2: 6.0

这是我尝试过的代码,但我得到了错误的输出和

显示意外的类标签。

public class Total {

 public static class Map extends Mapper<LongWritable, Text, Text, DoubleWritable> {
    private final static DoubleWritable one = new DoubleWritable();
    private Text word = new Text();

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString();
        StringTokenizer tokenizer = new StringTokenizer(line);
        word.set(tokenizer.nextToken());
        while (tokenizer.hasMoreTokens()) {
            one.set(Double.valueOf(tokenizer.nextToken()));
            context.write(word, one);                                           
        }
    }
 } 

 public static class Reduce extends Reducer<Text, DoubleWritable, Text, DoubleWritable> {
    private Text Msg = new Text();


    public void reduce(Text key, Iterable<DoubleWritable> values, Context context) 
      throws IOException, InterruptedException {
       firstMsg.set("label " + key+": Total");

       Double sum = 0.0;

         for (DoubleWritable val : values) {

            sum += val.get();


        }

        context.write(Msg, new DoubleWritable(sum));

    }
 }
//void method implementation also exists
}

【问题讨论】:

    标签: java hadoop mapreduce hdfs hadoop2


    【解决方案1】:

    您的目标是将所有相同的键放入它们自己的减速器中,以便您可以对数字求和。

    所以,拿着这个

    1     5.0    4.0   6.0
    2     2.0    1.0   3.0
    1     3.0    4.0   8.0
    

    并从本质上创建这个

    1     [(5 .0    4.0   6.0), (3.0    4.0   8.0)]
    2     [(2.0    1.0   3.0)]
    

    因此,您的地图应该只输出键 1 和 2,每个键后面都有剩余的值,每个键不一定有很多值。

    为此,您可以使用Mapper&lt;LongWritable, Text, Text, Text&gt;。 (将输出数据类型更改为Text

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString();
    
        StringTokenizer tokenizer = new StringTokenizer(line);
        word.set("label " + tokenizer.nextToken());
    
        StringBuilder remainder = new StringBuilder();
        while (tokenizer.hasMoreTokens()) {
            remainder.append(tokenizer.nextToken()).append(",");                                        
        }
        String output = remainder.setLength(remainder.getLength() - 1).toString()
        context.write(word, new Text(output));  
    }
    

    然后,在 Reducer 中,将其设为 Reducer&lt;Text, Text, Text, DoubleWritable&gt;(以 (Text,Text) 对读取),您现在有一个 Iterable&lt;Text&gt; values,它是逗号分隔字符串的可迭代对象,您可以将其解析为双精度,并取累计总和。

    你并不真的需要 reducer 中的 firstMsg.set 部分——这可以在 mapper 中完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-08
      • 1970-01-01
      • 1970-01-01
      • 2022-07-21
      • 2013-07-23
      • 2012-05-14
      • 2012-10-30
      • 1970-01-01
      相关资源
      最近更新 更多