Hadoop map-reduce中中值的计算
有人能举例说明map reduce中中值/分位数的计算吗 我对Datafu中值的理解是“n”映射器对 并将数据发送至负责分拣的“1”减速器 从n个制图器中获取所有数据并找到中值(中间值) 我的理解正确吗 如果是,这种方法是否适用于 大量的数据,因为我可以清楚地看到一个单一的减速机 努力完成最后的任务。 感谢要在一系列中找到中间值(中间值),需要将1个减速机传递给整个数字范围,以确定哪个是“中间”值 根据输入集中值的范围和唯一性,可以引入组合器来输出每个值的频率,从而减少发送到单个减速机的映射输出的数量。然后,减速机可以使用排序值/频率对来识别中值 另一种扩展方法(如果您知道值的范围和粗略分布,请再次使用)是使用自定义分区器,该分区器按范围存储桶(0-99转到reducer 0,100-199转到reducer 2,依此类推)分配键。但是,这将需要一些辅助工作来检查减速器输出并执行最终的中值计算(例如,知道每个减速器中的键数,可以计算哪个减速器输出将包含中值,以及在哪个偏移量)O((n log n)/p)对其排序,然后O(1)获得中值 是的。。。您可以获得O(n/p),但不能使用Hadoop中的开箱即用排序功能。除非你能证明2-20小时的开发时间来编码并行的第k个最大算法,否则我只需要排序并获取中心项。你真的需要精确的中位数和分位数吗 很多时候,您最好只获取近似值,并使用它们,特别是在您将其用于数据分区的情况下 事实上,您可以使用近似分位数加快查找精确分位数的速度(实际上是在Hadoop map-reduce中中值的计算,hadoop,statistics,mapreduce,apache-pig,median,Hadoop,Statistics,Mapreduce,Apache Pig,Median,有人能举例说明map reduce中中值/分位数的计算吗 我对Datafu中值的理解是“n”映射器对 并将数据发送至负责分拣的“1”减速器 从n个制图器中获取所有数据并找到中值(中间值) 我的理解正确吗 如果是,这种方法是否适用于 大量的数据,因为我可以清楚地看到一个单一的减速机 努力完成最后的任务。 感谢要在一系列中找到中间值(中间值),需要将1个减速机传递给整个数字范围,以确定哪个是“中间”值 根据输入集中值的范围和唯一性,可以引入组合器来输出每个值的频率,从而减少发送到单个减速机的映射输出
O(n/p)
时间内),下面是该策略的大致轮廓:
O(n)
中)以查找真正的分位数O(n)
网络流量。
您可能可以通过为第一次迭代选择“备用”分位数来优化该过程。比如说,你想找到全球中值。在线性过程中很难找到它,但当它被划分为k个分区时,可以将其缩小到数据集的1/kt。因此,与其让每个节点报告其中值,不如让每个节点另外报告(k-1)/(2k)和(k+1)/(2k)处的对象。这将允许您缩小真实中值必须显著位于的值范围。因此,在下一步中,您可以让每个节点将所需范围内的对象发送到单个主节点,并仅选择该范围内的中间值。在许多真实场景中,数据集中的值基数相对较小。在这种情况下,可以通过两个MapReduce作业有效地解决问题:
n
(n
=值集的基数
)项,而不必像原始方法那样处理所有值
下面是作业2的示例。这是可以直接用于Hadoop流的python脚本。假设数据集中的值为ints
,但可以很容易地用于double
s
import sys
item_to_index_range = []
total_count = 0
# Store in memory a mapping of a value to the range of indexes it has in a sorted list of all values
for line in sys.stdin:
item, count = line.strip().split("\t", 1)
new_total_count = total_count + int(count)
item_to_index_range.append((item, (total_count + 1, new_total_count + 1)))
total_count = new_total_count
# Calculate index(es) of middle items
middle_items_indexes = [(total_count / 2) + 1]
if total_count % 2 == 0:
middle_items_indexes += [total_count / 2]
# Retrieve middle item(s)
middle_items = []
for i in middle_items_indexes:
for item, index_range in item_to_index_range:
if i in range(*index_range):
middle_items.append(item)
continue
print sum(middle_items) / float(len(middle_items))
这个答案建立在最初来自of的建议之上。答案建议使用组合器作为计算值频率的平均值。然而,在MapReduce中,组合器不能保证总是执行。这有一些副作用:
- 减速器首先必须计算最终<值-频率>对,然后计算中值李>
- 在最坏的情况下,组合器将永远不会执行,减速机仍将不得不处理所有单个值