Hadoop: результат MapReduce MinMax отличается от исходного набора данных - PullRequest
1 голос
/ 04 июня 2019

Я новичок в 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

Очевидно, что результат не соответствует исходным данным ... Но я не могу понять, почему это происходит ...

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Ваш код имеет несколько проблем.

(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) ВКартографическая функция, которую вы заключаете в код IOException catch-блоков.Это не имеет никакого смысла.Если во входных данных есть записи в неправильном формате, то, скорее всего, вы получите NullPointerException / NumberFormatError в Double.parseDouble().Однако вы не обрабатываете эти исключения.

Проверка на нулевые значения после того, как вы позвонили parseDouble, также не имеет смысла.

(3) Вы передаете ключ карты редуктору как Text,Я бы посоветовал указать год как IntWritable (и сконфигурировать свою работу с job.setMapOutputKeyClass(IntWritable.class);).

(4) maxExposure должен обрабатываться аналогично minExposure в коде редуктора.В настоящее время вы просто возвращаете значение для последней записи.

1 голос
/ 04 июня 2019

Ваша логика найти минимальную и максимальную экспозицию в редукторе, похоже, отключена.Вы устанавливаете 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...