Как сгенерировать номер строки у свиньи? - PullRequest
4 голосов
/ 01 марта 2012

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

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

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

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

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

Спасибо за чтение этого вопроса!

Ответы [ 4 ]

10 голосов
/ 14 июня 2013

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

3 голосов
/ 19 июля 2012

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

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

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

1 голос
/ 06 декабря 2013

@ cabad

На первый взгляд кажется, что оператор 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)                
1 голос
/ 04 ноября 2012

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

  1. WITH_GROUPS = foreach TABLE генерирует имя, name / 100 as group_id;
  2. group WITH_GROUPS by group_id;
  3. PER_GROUP = generategroup, count (*);
  4. ACCUM_PER_GROUP = перекрестное объединение PER_GROUP с самим собой, вычисление совокупного счета на группу;
  5. cogroup ACCUM_PER_GROUP с WITH_GROUPS by group_id;
  6. в прогоне редуктораUDF, который присваивает каждой строке идентификатор, начиная с этой группы аккумулятивно-числовой
...