Python3 MRJob выводит несортированные пары ключ-значение

Контекст

Python 3.6.3 :: Anaconda custom (64-разрядная версия)
mrjob == 0.6.2 без специальной конфигурации
Запуск локально

Я реализую базовый пример подсчета слов для работы по сокращению локальной карты. Мой картограф сопоставляет 1 каждому слову в каждой строке книги из файла .txt, используя простое регулярное выражение. Редуктор считает количество вхождений каждого слова, то есть количество единиц, сгруппированных в каждое слово.

from mrjob.job import MRJob
import re

WORD_REGEXP = re.compile(r"[\w']+")

class WordCounter(MRJob):
  def mapper(self, _, line):
    words = WORD_REGEXP.findall(line)
    for word in words:
      yield word.lower(), 1

  def reducer(self, word, times_seen):
    yield word, sum(times_seen)

if __name__ == '__main__':
  WordCounter.run()

Проблема

Выходной файл правильный, но пары ключ-значение не отсортированы глобально. Похоже, что результат сортируется только в алфавитном порядке по кускам данных.

"customers'"    1
"customizing"   1
"cut"   2
"cycle" 1
"cycles"    1
"d" 10
"dad"   1
"dada"  1
"daily" 3
"damage"    1
"deductible"    6
...
"exchange"  10
"excited"   4
"excitement"    1
"exciting"  4
"executive" 2
"executives"    2
"theft" 1
"their" 122
"them"  166
"theme" 2
"themselves"    16
"then"  59
"there" 144
"they've"   2
...
"anecdotes" 1
"angel" 1
"angie's"   1
"angry" 1
"announce"  2
"announced" 1
"announcement"  3
"announcements" 3
"announcing"    2
...
"patents"   3
"path"  19
"paths" 1
"patterns"  1
"pay"   45
"exercise"  1
"exercises" 1
"exist" 6
"expansion" 1
"expect"    11
"expectation"   3
"expectations"  5
"expected"  4
....
"customer"  41
"customers" 122
"yours" 15
"yourself"  78
"youth" 1
"zealand"   1
"zero"  7
"zoho"  1
"zone"  2

Вопрос

Нужно ли выполнить некоторую начальную настройку, чтобы получить глобально отсортированный вывод из MRJob?


person ekauffmann    schedule 09.05.2018    source источник


Ответы (1)


Вам не хватает шага комбайнера, в этом руководстве это первый пример одноэтапного задания: https://mrjob.readthedocs.io/en/latest/guides/writing-mrjobs.html

Скопирую код для полноты ответа:

from mrjob.job import MRJob
import re

WORD_RE = re.compile(r"[\w']+")


class MRWordFreqCount(MRJob):

    def mapper(self, _, line):
        for word in WORD_RE.findall(line):
            yield word.lower(), 1

    def combiner(self, word, counts):
        yield word, sum(counts)

    def reducer(self, word, counts):
        yield word, sum(counts)


if __name__ == '__main__':
    MRWordFreqCount.run()
person Emilio Aburto    schedule 10.05.2018
comment
Объединитель - это необязательный этап задания mapreduce, который используется для уменьшения перегрузки сети. Я считаю, что это не источник моей проблемы. Как бы то ни было, я попытался добавить комбайнер, но результат остался несортированным. - person ekauffmann; 12.05.2018
comment
Ах да, извините, похоже, что алгоритм упорядочивает вывод до тех пор, пока не будет достигнут определенный размер, и тогда это больше не беспокоит. Вы пробовали постобработку результатов? Я имею в виду что-то вроде этого stackoverflow.com/a/5737935 - person Emilio Aburto; 23.05.2018