我想尝试使用 Mincemeat map/reduce Python 应用程序进行矩阵乘法。我正在使用 Python 2.7。我发现了几个描述如何在 Java 中使用 Hadoop 进行矩阵乘法的网页,我一直在参考这个http://importantfish.com/one-step-matrix-multiplication-with-hadoop/因为它很简单并且因为它显示的伪代码已经非常接近 Python 代码。
我注意到在 Java 代码中还包含矩阵维度,通过附加的 Context 类型参数提供给 map 和 reduce 函数。Mincemeat 没有提供这样的东西,但我得到了一个建议,我可以将这些值提供给我的 map 并使用闭包来减少函数。我写的 map 和 reduce 函数是这样的:
def make_map_fn(num_rows_result, num_cols_result):
m = num_rows_result
p = num_cols_result
def map_fn(key, value):
# value is ('A', i, j, a_ij) or ('B', j, k, b_jk)
if value[0] == 'A':
i = value[1]
j = value[2]
a_ij = value[3]
for k in xrange(1, p):
yield ((i, k), ('A', j, a_ij))
else:
j = value[1]
k = value[2]
b_jk = value[3]
for i in xrange(1, m):
yield ((i, k), ('B', j, b_jk))
return map_fn
def make_reduce_fn(inner_dim):
n = inner_dim
def reduce_fn(key, values):
# key is (i, k)
# values is a list of ('A', j, a_ij) and ('B', j, b_jk)
hash_A = {j: a_ij for (x, j, a_ij) in values if x == 'A'}
hash_B = {j: b_jk for (x, j, b_jk) in values if x == 'B'}
result = 0
for j in xrange(1, n):
result += hash_A[j] * hash_B[j]
return (key, result)
return reduce_fn
然后我将它们分配给 Mincemeat,如下所示:
s = mincemeat.Server()
s.mapfn = make_map_fn(num_rows_A, num_cols_B)
s.reducefn = make_reduce_fn(num_cols_A)
当我在 Mincemeat 中运行它时,我收到以下错误消息:
error: uncaptured python exception, closing channel <__main__.Client connected at 0x2ada4d0>
(<type 'exceptions.TypeError'>:arg 5 (closure) must be tuple
[/usr/lib/python2.7/asyncore.py|read|83]
[/usr/lib/python2.7/asyncore.py|handle_read_event|444]
[/usr/lib/python2.7/asynchat.py|handle_read|140]
[/usr/local/lib/python2.7/dist-packages/mincemeat.py|found_terminator|96]
[/usr/local/lib/python2.7/dist-packages/mincemeat.py|process_command|194]
[/usr/local/lib/python2.7/dist-packages/mincemeat.py|set_mapfn|159])
我在网上搜索了 |python 闭包必须是元组 | 之类的搜索词。我发现的事情似乎是在处理有人试图使用 lambda 或 function() 构造函数的情况,并且需要确保他们在将它们定义为闭包时没有忽略某些事情。在我的例子中,make_map_fn 和 make_reduce_fn 返回的 map_fn 和 reduce_fn 值看起来像有效的函数对象,它们的 func_closure 值是包含我想要提供的数组维度的单元格元组,但仍然缺少一些东西。我需要以什么形式传递这些函数才能供 Mincemeat 使用?