Могу ли я использовать Combiner для вычисления среднего значения в задании mapreduce?

Я хочу реализовать задание mapreduce, которое читает файлы паркета со следующей схемой:

{
  optional int96 dropoff_datetime;
  optional float dropoff_latitude;
  optional float dropoff_longitude;
  optional int32 dropoff_taxizone_id;
  optional float ehail_fee;
  optional float extra;
  optional float fare_amount;
  optional float improvement_surcharge;
  optional float mta_tax;
  optional int32 passenger_count;
  optional binary payment_type (UTF8);
  optional int96 pickup_datetime;
  optional float pickup_latitude;
  optional float pickup_longitude;
  optional int32 pickup_taxizone_id;
  optional int32 rate_code_id;
  optional binary store_and_fwd_flag (UTF8);
  optional float tip_amount;
  optional float tolls_amount;
  optional float total_amount;
  optional float trip_distance;
  optional binary trip_type (UTF8);
  optional binary vendor_id (UTF8);
  required int64 trip_id;
}

Основной целью работы является вычисление средней скорости такси в поездках на каждый час в день (0->23).

Мой класс Mapper вычисляет скорость для каждого часа погрузки, поэтому он предоставляет следующую пару (час, скорость).

Класс Reducer обычно должен вычислять среднее значение скорости за каждый час.

Однако мне интересно, могу ли я использовать класс объединителя для облегчения прецессии данных, потому что я узнал, что классы объединителя можно использовать только с коммутативными и ассоциативными операциями, а это не относится к среднему праву?

Любая помощь будет оценена.

Спасибо :)


person rafik_bougacha    schedule 07.03.2018    source источник


Ответы (1)


Комбайнер может помочь в вычислении средних значений. В основном вы хотите использовать объединитель, чтобы получить промежуточный итог, который вы можете использовать в редьюсере для расчета среднего.

На входе объединитель получит (hour, (speed, 1)), а на выходе он должен выдать (hour, (sum_speed, num_records)). Затем редуктор может вычислить среднее значение за каждый час, разделив sum_speed на num_records.

Например, если объединитель 1 получает на вход:

(1, (50, 1))
(1, (20, 1))
(1, (10, 1))
(23, (16, 1))

то он будет выводить:

(1, (80, 3))
(23, (16, 1))

и если объединитель 2 получает на вход:

(1, (20, 1))
(23, (40, 1))

то он будет выводить:

(1, (20, 1))
(23, (40, 1))

затем редуктор снова суммирует их перед делением:

(1, (80+20, 3+1)) = (1, (100, 4)) = (1, 25) 
(23, (16+40, 1+1)) = (23, (56, 2)) = (23, 28)

давая вам ваши ответы в форме (hour, average_speed).

person Ben Watson    schedule 07.03.2018
comment
Большое спасибо за ваш ответ, я думаю об этом решении, однако пара (sum_speed, num_records) также должна быть значением вывода преобразователя, потому что объединитель и преобразователь должны иметь те же типы ключей/значений, которые я знаю. - person rafik_bougacha; 07.03.2018
comment
Извините, вы правы. Давно не делал МРТ :). Обновил ответ. - person Ben Watson; 07.03.2018