Как сгенерировать номер строки в свинье?

Я использую свинью для подготовки данных, и столкнулся с проблемой, которая кажется простой, но я не могу с ней справиться:

например, у меня есть столбец имен

name
------
Alicia
Ana
Benita 
Berta 
Bertha 

тогда как я могу добавить номер строки для каждого имени? результат будет таким:

name    |  id
----------------
Alicia  |  1
Ana     |  2
Benita  |  3
Berta   |  4
Bertha  |  5

Спасибо, что прочитали этот вопрос!


person Breakinen    schedule 01.03.2012    source источник


Ответы (4)


К сожалению, в Pig Latin нет возможности перечислить строки. По крайней мере, я не мог найти простой способ. Одним из решений является реализация отдельного задания MapReduce с одной задачей Reduce, которая выполняет фактическое перечисление. Чтобы быть более точным,

Фаза сопоставления: назначьте все строки одному и тому же ключу. Задача Single Reduce: получает один ключ с итератором для всех строк. Поскольку задача сокращения будет выполняться только на 1 физической машине, а «функция сокращения» будет вызываться только один раз, локальный счетчик внутри функции решает проблему.

Если данные огромны и их невозможно обработать на одном компьютере, то можно использовать счетчики MapReduce по умолчанию на главном узле.

person Shatlyk Ashyralyyev    schedule 19.07.2012
comment
Спасибо, Шатлык, на свинской латыни тоже не нашел. Да, ваша идея использовать только 1 узел сокращения может решить проблему, хотя это не совсем параллельный алгоритм. - person Breakinen; 21.07.2012
comment
Поскольку редюсеру необходимо обрабатывать данные, которые имеют тот же размер, что и весь ввод картографа, это станет узким местом программы уменьшения карты. Я думаю, что очень сложно реализовать действительно параллельную программу, подобную этой, поскольку средства отслеживания задач не могут поддерживать глобальную переменную ^^ Кстати, наконец, я решил эту проблему, просто используя программу Java на одной машине, это быстро :) - person Breakinen; 21.07.2012

У свиньи не было механизма для этого, когда вы задали этот вопрос. Однако в Pig 0.11 появился оператор RANK, который можно использовать для этой цели.

person cabad    schedule 14.06.2013

эскиз, предполагая, что столбец «имя», по которому мы хотим упорядочить, является числовым, а не строковым. также предполагая хорошее неперекошенное распределение.

  1. WITH_GROUPS = foreach TABLE генерирует имя, имя / 100 как group_id;
  2. сгруппировать WITH_GROUPS по group_id;
  3. PER_GROUP = создать группу, count(*);
  4. ACCUM_PER_GROUP = перекрестное соединение PER_GROUP с самим собой, вычисление накопительного количества для каждой группы;
  5. совместно сгруппировать ACCUM_PER_GROUP с WITH_GROUPS по group_id;
  6. в редукторе запустите UDF, который присваивает каждой строке идентификатор, начиная с этой группы accumulative_count
person ihadanny    schedule 04.11.2012

@кабад

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

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

См. этот пример из [документов] http://pig.apache.org/docs/r0.11.0/basic.html#rank (ранги 2, 6, 10):

C = rank A by f1 DESC, f2 ASC;

dump C;
(1,Tete,2,N)
(2,Ranjit,3,M)
(2,Ranjit,3,P)
(4,Michael,8,T)
(5,Jose,10,V)
(6,Jillian,8,Q)
(6,Jillian,8,Q)
(8,JaePak,7,Q)
(9,David,1,N)
(10,David,4,Q)
(10,David,4,Q)                
person Matt Davies    schedule 06.12.2013
comment
Для варианта использования, описанного OP, простой RANK A; должно сработать. - person cabad; 17.03.2014