我正在尝试预处理XML文件以在放入mapreduce之前提取某些节点。我有以下代码:
from mrjob.compat import jobconf_from_env
from mrjob.job import MRJob
from mrjob.util import cmd_line, bash_wrap
class MRCountLinesByFile(MRJob):
def configure_options(self):
super(MRCountLinesByFile, self).configure_options()
self.add_file_option('--filter')
def mapper_cmd(self):
cmd = cmd_line([self.options.filter, jobconf_from_env('mapreduce.map.input.file'])
return cmd
if __name__ == '__main__':
MRCountLinesByFile.run()
在命令行中,我输入:
python3 test_job_conf.py --filter ./filter.py -r local < test.txt
test.txt
是一个普通的XML文件,如here。虽然filter.py
是一个查找所有标题信息的脚本。
但是,我收到以下错误:
Creating temp directory /tmp/test_job_conf.vagrant.20160406.042648.689625
Running step 1 of 1...
Traceback (most recent call last):
File "./filter.py", line 8, in <module>
with open(filename) as f:
FileNotFoundError: [Errno 2] No such file or directory: 'None'
Step 1 of 1 failed: Command '['./filter.py', 'None']' returned non-zero exit status 1
在这种情况下看起来像mapreduce.map.input.file
渲染None
。如何让mapper_cmd
函数读取mrjob
当前正在阅读的文件?
答案 0 :(得分:0)
根据我的理解,你的self.add_file_option应该有你文件的路径。
self.add_file_option('--items', help='Path to u.item')
我不太了解你的情况,但这是我的理解。 您可以使用configure选项确保将给定文件发送给所有映射器以进行处理,例如,当您要对除源以外的其他文件中的数据进行辅助查找时。这个辅助查找文件由self.add_file_option提供(&#39; - items&#39;,help =&#39; path to u.item&#39;)。
要在reducer或mapper阶段之前预先处理某些内容,请使用reducer_init或mapper_init。这些初始化或处理步骤也需要在步骤函数中提及,例如下面所示。
def steps(self):
return [
MRStep(mapper=self.mapper_get_name,
reducer_init=self.reducer_init,
reducer=self.reducer_count_name),
MRStep(reducer = self.reducer_find_maxname)
]
在init函数中,您需要对发送到mapper或reducer之前需要完成的事情进行实际的预处理。比如说打开一个文件xyz并复制我将在我的reducer中使用的另一个字段的第一个字段中的值并输出相同的内容。
def reducer_init(self):
self.movieNames = {}
with open("xyz") as f:
for line in f:
fields = line.split('|')
self.myNames[fields[0]] = fields[1]
希望这会有所帮助!!