我想计算一组数据的居中移动平均值。
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 谢谢
答案 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的一部分)。可以做两个不同的幻灯片,类似于分区。