【问题标题】:Hadoop: MapReduce MinMax result different from original datasetHadoop:MapReduce MinMax 结果与原始数据集不同
【发布时间】:2019-06-04 05:13:58
【问题描述】:

我是 Hadoop 的新手。 我尝试使用 MapReduce 来获取每年的最小和最大月降水量值。 下面是一年数据集的样子:

Product code,Station number,Year,Month,Monthly Precipitation Total (millimetres),Quality
IDCJAC0001,023000,1839,01,11.5,Y
IDCJAC0001,023000,1839,02,11.4,Y
IDCJAC0001,023000,1839,03,20.8,Y
IDCJAC0001,023000,1839,04,10.5,Y
IDCJAC0001,023000,1839,05,4.8,Y
IDCJAC0001,023000,1839,06,90.4,Y
IDCJAC0001,023000,1839,07,54.2,Y
IDCJAC0001,023000,1839,08,97.4,Y
IDCJAC0001,023000,1839,09,41.4,Y
IDCJAC0001,023000,1839,10,40.8,Y
IDCJAC0001,023000,1839,11,113.2,Y
IDCJAC0001,023000,1839,12,8.9,Y

这就是我在 1839 年得到的结果:

1839    1.31709005E9    1.3172928E9

很明显,结果与原始数据不匹配……但我不知道为什么会这样……

【问题讨论】:

    标签: java hadoop


    【解决方案1】:

    您的代码有多个问题。

    (1) 在MinMixExposure 中,您写入双精度,但读取整数。您还使用 Double 类型(意味着您关心空值),但不处理序列化/反序列化中的空值。如果你真的需要空值,你应该这样写:

    // write
    out.writeBoolean(value != null);
    if (value != null) {
      out.writeDouble(value);
    }
    
    // read
    if (in.readBoolean()) {
      value = in.readDouble();
    } else {
      value = null;
    }
    

    如果您不需要存储空值,请将Double 替换为double

    (2) 在 map 函数中,您将代码包装在 IOException catch 块中。这没有任何意义。如果输入数据的记录格式不正确,那么您很可能会在Double.parseDouble() 中得到NullPointerException/NumberFormatError。但是,您不处理这些异常。

    在调用parseDouble 之后检查空值也没有意义。

    (3) 您将映射键作为Text 传递给reducer。我建议以IntWritable 传递年份(并使用job.setMapOutputKeyClass(IntWritable.class); 配置您的工作)。

    (4) maxExposure 的处理方式必须与 reducer 代码中的 minExposure 类似。目前您只返回最后一条记录的值。

    【讨论】:

      【解决方案2】:

      您在 Reducer 中查找最小和最大曝光的逻辑似乎不正确。你设置maxExposure 两次,从不检查它是否真的是最大曝光。我会选择:

      public void reduce(Text key, Iterable<MinMaxExposure> values,
              Context context) throws IOException, InterruptedException {
          Double minExposure = Double.MAX_VALUE;
          Double maxExposure = Double.MIN_VALUE;
      
          for (MinMaxExposure val : values) {
              if (val.getMinExposure() < minExposure) {
                  minExposure = val.getMinExposure();  
              }
      
              if (val.getMaxExposure() > maxExposure) {
                  maxExposure = val.getMaxExposure();  
              }
          }
      
          MinMaxExposure resultRow = new MinMaxExposure();
          resultRow.setMinExposure(minExposure);
          resultRow.setMaxExposure(maxExposure);
          context.write(key, resultRow);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-07
        • 2015-07-18
        • 1970-01-01
        相关资源
        最近更新 更多