mrjob: как в Примере автоматически узнать, как найти строки в текстовом файле?
Я пытаюсь лучше понять пример для mrjob
from mrjob.job import MRJob
class MRWordFrequencyCount(MRJob):
def mapper(self, _, line):
yield "chars", len(line)
yield "words", len(line.split())
yield "lines", 1
def reducer(self, key, values):
yield key, sum(values)
if __name__ == '__main__':
MRWordFrequencyCount.run()
Я управляю им по
$ python word_count.py my_file.txt
И он работает, как и ожидалось, но я не понимаю, как он автоматически знает, что он собирается прочитать текстовый файл и разделить его на каждую строку. и я тоже не уверен, что делает _.
Из того, что я понимаю, mapper() генерирует три пары ключ / значение для каждой строки правильно? Что делать, если я хочу работать с каждым файлом в папке?
И reducer() автоматически знают, как добавить значения каждого ключа повышаются?
Что делать,если я хочу запустить модульные тесты через map reduce, как будут выглядеть картограф и редуктор? Это вообще необходимо?
3 ответов:
Метод mapper получает пару ключ-значение, уже проанализированную из входного текста. mrjob использует потоковую передачу Hadoop, и каждый входной текст разделяется новым символом строки, а затем каждая строка разбивается на пару ключ-значение на основе используемого входного протокола. Это то, о чем заботится фреймворк, поэтому вам не нужно поднимать тяжести; вы можете просто предположить, что получите правильный ключ и ценность.
Однако необходимо указать, какой тип входных текстовых файлов задан. Например, если ключ и/или значение являются не обычным текстом (как в исходном вопросе), а сериализованным JSON, то вы используете JSONProtocol / JSONValueProtocol и т. д., вместо RawValueProtocol, который используется по умолчанию.
Для начального картографа каждая строка считывается в значение (RawValueProtocol), поэтому вы не получаете ключ. Использование
_- это всего лишь соглашение Python для неиспользуемой фиктивной переменной. (Однако_На самом деле является допустимым именем для переменной Python. Вы можете сделать что-то вроде этогоa = 3; _ = 2; b = a + _. Богохульство, не так ли?)Mrjob может принимать несколько входных файлов. Вы можете сделать, например,
$ python wordcount.py text1.txt text2.txtЕсли вы хотите, чтобы все текстовые файлы входили в задание mrjob, вы можете сделать такие вещи, как
$ python wordcount.py inputdir/*.txtИли просто
$ python wordcount.py inputdirИ все выбранные файлы используются в качестве входных данных.
Редуктор получает ключ и итератор для всех значений, связанных с этим ключом. Так что, если вы пример, переменная
valuesв методе редуктора является итератором. Если вы хотите это сделать что-то над всеми значениями, вам нужно фактически перебрать их все. В конкретном примере в вопросе встроенная функцияsumможет принимать итератор в качестве аргумента, и именно поэтому вы можете сделать это одним выстрелом. Но это фактически похоже наsum([value for value in values]).На самом деле я не знаю, как вы будете тестировать сценарии mrjob. Обычно я просто тестировал на небольшом куске тестовых данных перед запуском в производство.
Я мало что знаю о мистере Джобе,поэтому сделаю несколько предположений. Во-первых, _ означает игнорировать ключ (проверенный после поиска в Google). Во-вторых, я бы предположил, что он будет работать с разделенным запятыми списком файлов или каталогом. Далее, этот код лишен настройки, вероятно, потому, что это имена методов по умолчанию. Я уверен, что если бы вы назвали свой картограф или редуктор чем-то другим, мистер джоб не смог бы подобрать его автоматически.
Я нашел несколько примеров здесь.
from mrjob.job import MRJob class MRRatingCounter(MRJob): def mapper(self, key, line): (userID, movieID, rating, timestamp) = line.split('\t') yield rating, 1 def reducer(self, rating, occurences): yield rating, sum(occurences) if __name__ == '__main__': MRRatingCounter.run()Поэтому, пожалуйста, поправьте меня на основе вышеизложенного обсуждения:
Пожалуйста, поправьте меня, если я ошибаюсь, поэтому в этом случае ключ принимает значение входного файла в этом случае я могу прочитать его в своем уме так:
Def mapper (self{ this is the object / instance}, key{ input text file в данном случае имя файла, который является и корректным me ml-100k / u.data, line{ this is the are trying to pass to mapper () every time from the data file .,)
Другой код из Udemy, где i я пытаюсь узнать, как задан первоначальный вопрос : класс MRFriendsByAge(MRJob):
def mapper(self, _, line): (ID, name, age, numFriends) = line.split(',') yield age, float(numFriends) def reducer(self, age, numFriends): total = 0 numElements = 0 for x in numFriends: total += x numElements += 1 yield age, total / numElementsЕсли имя == 'main ': MRFriendsByAge.run ()
Нашел книгу работы мистера и пытаюсь понять, есть ли в ней смысл, но я все еще борюсь
Comments