【问题标题】:MapReduce pairwise comparison of all lines in multiple filesMapReduce对多个文件中所有行的成对比较
【发布时间】:2011-07-10 20:38:34
【问题描述】:

我开始使用 python 的mrjob 将我的一些长期运行的 python 程序转换为 MapReduce hadoop 作业。我已经得到了简单的字数统计示例,并且我从概念上理解了“文本分类”示例。

但是,我在确定解决问题所需的步骤时遇到了一些麻烦。

我有多个文件(大约 6000 个),每个文件有 2 到 800 行。在这种情况下,每一行都是一个简单的以空格分隔的“信号”。我需要比较每个文件中的每一行与所有文件(包括其自身)中的每一行之间的相关性。然后根据相关系数输出结果。

一个文件的例子:

1 2 3 4 2 3 1 2 3 4 1 2
2 2 3 1 3 3 1 2 3 1 4 1
2 3 4 5 3 2 1 3 4 5 2 1
...

我需要将此文件的每一行与其他每个文件中的每一行配对...或者如果这样更容易,我可以将所有文件连接到一个文件中,但我仍然需要成对迭代。

我了解如何进行计算以及如何使用最后的 reduce 步骤来聚合和过滤结果。我遇到的困难是如何在不读取单个 setp 中的所有文件的情况下将所有成对项目yield 连续步骤?我想我可以提前准备一个使用itertools.product 的输入文件,但这个文件会大得令人望而却步。

【问题讨论】:

  • 你能提供一些示例数据吗?
  • 当然,刚刚添加了一些:)
  • 也许我可以先使用reduce 步骤并为所有行提供相同的键,以便函数获取所有行...然后使用itertools.productyield 所有对正确键。不确定这是否是正确的做事方式。
  • 遗憾的是,这已经比原来的项目数量减少了很多......但一般来说 N 约为 40,000。我已经在我的单台机器上运行它大约 4 天完成......所以它不在合理范围内。
  • 再一次,当你对问题的最初概念导致算法的运行时间为 4 天时,答案不是使用 Hadoop/map-reduce,而是找到算法更改以降低问题复杂性.我不能说我理解你在做什么,但这是我的一般观察。

标签: python mapreduce mrjob


【解决方案1】:

好吧,既然没有人想出答案,我会发布我目前的解决方法,以防其他人需要它。我不确定这是多么“规范”或高效,但它到目前为止有效。

我将文件名作为文件每一行的第一项,然后是\t,然后是其余数据。对于这个例子,我只是在每一行上使用一个数字,然后对它们进行平均,这只是一个非常简单的例子。

然后我在mrjob 中进行了以下map-reduce 步骤。

class MRAvgPairwiseLines(MRJob):

def input_mapper(self, _, value):
    """Takes each input line and converts it to (fnum, num) and a key of 'ALL'"""

    fnum, val = value.split('\t')
    yield 'ALL', (fnum, val)

def input_reducer(self, key, values):

    for (fnum1, val1), (fnum2, val2) in product(values, repeat = 2):
        yield fnum1, (fnum1, fnum2, val1, val2)

def do_avg(self, key, value):

    fnum1, fnum2, val1, val2 = value
    res = (float(val1)+float(val2))/float(2)
    yield key, (fnum2, res)

def get_max_avg(self, key, values):

    max_fnum, max_avg = max(values, key = lambda x: x[1])
    yield key, (max_fnum, max_avg)

def steps(self):
    return [self.mr(mapper=self.input_mapper, reducer=self.input_reducer),
                self.mr(mapper=self.do_avg, reducer=self.get_max_avg)]

这样,input_mapper 函数的所有输出都被分组到相同的 input_reducer 中,然后 yields 连续对。然后将它们传递到适当的位置,最终返回最大的平均值(这实际上是所有其他文件中最大的项目)。

希望对某人有所帮助。

【讨论】:

  • 所以你最终将整个笛卡尔积加载到内存中?
猜你喜欢
  • 2022-01-25
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 2013-11-24
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 2012-01-25
相关资源
最近更新 更多