如何计算Hadoop Map-Reduce中一组数据的居中移动平均值?

时间:2012-09-17 07:50:18

标签: java hadoop mapreduce

我想计算一组数据的居中移动平均值。

Example Input format :

quarter | sales      
Q1'11   | 9            
Q2'11   | 8
Q3'11   | 9
Q4'11   | 12
Q1'12   | 9
Q2'12   | 12
Q3'12   | 9
Q4'12   | 10

数据的数学表示和移动平均值的计算,然后是居中的移动平均值

Period   Value   MA  Centered
1          9
1.5
2          8
2.5              9.5
3          9            9.5
3.5              9.5
4          12           10.0
4.5              10.5
5          9            10.750
5.5              11.0
6          12
6.5
7          9  

我坚持使用RecordReader的实现,它将提供一年即四季度的映射器销售价值。 The RecordReader Problem Question Thread 谢谢

2 个答案:

答案 0 :(得分:2)

这在MapReduce范例中实际上是完全可行的;它不一定是一个“滑动窗口”。相反,请考虑每个数据点与最多四次MA计算相关的事实,并记住每次调用map函数都可以发出多个键值对。这是伪代码:

First MR job:

map(quarter, sales)
    emit(quarter - 1.5, sales)
    emit(quarter - 0.5, sales)
    emit(quarter + 0.5, sales)
    emit(quarter + 1.5, sales)

reduce(quarter, list_of_sales)
    if (list_of_sales.length == 4):
        emit(quarter, average(list_of_sales))
    endif


Second MR job:

map(quarter, MA)
    emit(quarter - 0.5, MA)
    emit(quarter + 0.5, MA)

reduce(quarter, list_of_MA)
    if (list_of_MA.length == 2):
        emit(quarter, average(list_of_sales))
    endif

答案 1 :(得分:1)

据我所知,移动平均线并不能很好地映射到MapReduce范例,因为它的计算基本上是对排序数据的“滑动窗口”,而MR则处理非排序的排序数据范围。
我看到的解决方案如下:
a)实现自定义分区程序,以便能够在两次运行中创建两个不同的分区。在每次运行中 您的减速器将获得不同的数据范围并计算适当的移动平均值 我会试着说明一下:
在减速器的首次运行数据应该是:
R1:Q1,Q2,Q3,Q4
R2:Q5,Q6,Q7,Q8
...

在这里你将得到一些Q的移动平均线。

在下一次运行中,您的Reducer应该获得如下数据: R1:Q1 ...... Q6
R2:Q6 ... Q10
R3:Q10..Q14

并计算剩余的移动平均线。
然后,您需要汇总结果。

自定义分区器的想法,它将有两种操作模式 - 每次分成相等的范围但有一些移位。在伪代码中它看起来像这样:
partition =(key + SHIFT)/(MAX_KEY / numOfPartitions);
哪里:  SHIFT将从配置中获取。
 MAX_KEY =密钥的最大值。为简单起见,我假设它们从零开始。

RecordReader,恕我直言不是一个解决方案,因为它仅限于特定的分割,不能滑过分割的边界。

另一种解决方案是实现拆分输入数据的自定义逻辑(它是InputFormat的一部分)。可以做两个不同的幻灯片,类似于分区。