MRJob и python - вывод файла .csv для Reducer?

Я использую модуль MRJob для Python 2.7. Я создал класс, наследуемый от MRJob, и правильно сопоставил все с помощью унаследованной функции сопоставления.

Проблема в том, что я хотел бы, чтобы функция редуктора выводила файл .csv... вот код редуктора:

def reducer(self, geo_key, info_list):
        info_list.insert(0, ['Name,Age,Gender,Height'])
        for set in info_list:
            yield set

Затем я запускаю в командной строке ---> python -m map_csv <inputfile.txt> outputfile.csv

Я продолжаю получать эту ошибку, и действительно не понимаю, почему:

Counters from step 1:
  Unencodable output:
    TypeError: 785

Параметр info_list в редюсере — это просто список, содержащий списки различных значений, соответствующих типам в заголовке (т.е.

[
['Bill', 28, 'Male',75],
['Emily', 16, 'Female',56],
['Jason', 21, 'Male',63]]

Есть идеи, в чем здесь проблема? Спасибо!


person William Dewayne Corrin III    schedule 24.06.2015    source источник
comment
Вы не должны использовать set в качестве имени переменной, но это не проблема.   -  person ChrisP    schedule 24.06.2015
comment
Ты прав! Хороший улов на этом. Спасибо   -  person William Dewayne Corrin III    schedule 24.06.2015


Ответы (1)


Для управления форматами ввода и вывода в mrjob необходимо использовать протоколы.

К счастью, существует пакет, реализующий CSV-протокол, который вы могли бы использовать — https://pypi.python.org/pypi/mr3px

Импортируйте пакет в свой рабочий скрипт

from mr3px.csvprotocol import CsvProtocol

Укажите протокол в своем классе работы

class CsvOutputJob(MRJob):
    ...
    OUTPUT_PROTOCOL = CsvProtocol  # write output as CSV

А затем просто yield ваш список (или кортеж) полей

def reducer(self, geo_key, info_list):
    for row in info_list:
        yield (None, row) 

Обратите внимание, что вы не можете надежно добавить строку заголовка к этому выводу, потому что Hadoop будет использовать несколько редукторов для параллельного создания вывода.

Чтобы использовать этот пакет в EMR, вам необходимо установить его на этапе начальной загрузки экземпляра, добавив элемент в раздел bootstrap вашей конфигурации.

runners:
  emr:
    ...
    bootstrap:
      - sudo apt-get install -y python-setuptools
      - sudo easy_install pip
      - sudo pip install mr3px

отказ от ответственности — я являюсь сопровождающим пакета mr3px, который является ответвлением от mr3po

person msharp    schedule 10.07.2015
comment
Спасибо за ваш ответ, у меня была такая же проблема, и ваше решение сработало отлично. Только одно, если я запускаю файл на своей локальной машине, он возвращает результат в нужном формате. Однако, когда я запускаю файл на emr, он возвращает эту ошибку. ImportError: Нет модуля с именем mr3px.csvprotocol. Нужно ли внести некоторые изменения в файл конфигурации. Спасибо - person Fahad Sarfraz; 21.02.2016
comment
Да, вам нужно будет установить пакет из pypi на этапе начальной загрузки EMR. В разделе bootstrap вашей конфигурации вам понадобится что-то вроде - sudo pip install mr3px - person msharp; 23.02.2016
comment
@FahadSarfraz Обновлен ответ, чтобы показать, как настроить задания EMR. - person msharp; 23.02.2016
comment
mr3px был очень хорош. Возможно, вам стоит обратить внимание на то, что в моем случае ячейки csv будут содержать дополнительные s в конце. Например, ячейка должна иметь abc. Вместо этого он будет содержать abc . - person aghd; 03.03.2019
comment
Я смог установить его с помощью: bootstrap: - sudo yum install -y python-setuptools - sudo easy_install pip - sudo pip install mr3px - person aghd; 04.03.2019
comment
Рад, что вы нашли это полезным @AminGhaderi - синтаксический анализ csv просто использует пакет Python stdlib под капотом. Возможно, вам придется сообщить классу протокола, что вы ожидаете другой символ кавычек. Попробуйте OUTPUT_PROTOCOL = CsvProtocol(quotechar="'") - person msharp; 05.03.2019