Перегруппировать в PigLatin

В PigLatin я хочу сгруппировать по 2 раза, чтобы выбрать строки с 2 разными законами.

У меня возникли проблемы с объяснением проблемы, поэтому вот пример. Допустим, я хочу получить характеристики людей, у которых ближайший к моему возраст ($my_age) и много денег.

Relation A is four columns, (name, address, zipcode, age, money)

B = GROUP A BY (address, zipcode); # group by the address

-- generate the address, the person's age ...

C = FOREACH B GENERATE group, MIN($my_age - age) AS min_age, FLATTEN(A);

D = FILTER C BY min_age == age

--Then group by as to select the richest, group by fails :

E = GROUP D BY group; or E = GROUP D BY (address, zipcode);

-- The end would work
D = FOREACH E GENERATE group, MAX(money) AS max_money, FLATTEN(A);

F = FILTER C BY max_money == money;

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


Другой более реалистичный пример:

У вас есть файл требований, например: iddem, idopedem, datedem

У вас есть файл операций, например: idope, labelope, dateope, idoftheday, infope.

Я хочу вернуть операции, соответствующие требованиям, например: idopedem соответствует ideope.

Dateope должен быть ближайшим к datedem.

Если datedem - date_ope > 0, то я должен выбрать операцию с max(idoftheday), иначе я должен выбрать операцию с min(idoftheday).

Relation A is 5 columns (idope,labelope,dateope,idoftheday,infope)
Relation B is 3 columns (iddem, idopedem, datedem)

C = JOIN A BY idope, B BY idopedem;

D = FOREACH E GENERATE iddem, idope, datedem, dateope, ABS(datedem - dateope) AS datedelta, idoftheday, infope;

E = GROUP C BY iddem;

F = FOREACH D GENERATE group, MIN(C.datedelta) AS deltamin, FLATTEN(D);

G = FILTER F BY deltamin == datedelta;

--Then I must group by another time as to select the min or max idoftheday
H = GROUP G BY group; --Does not work when dump
H = GROUP G BY iddem; --Does not work when dump

I = FOREACH H GENERATE group, (datedem - dateope >= 0 ? max(idoftheday) as idofdaysel : min(idoftheday) as idofdaysel), FLATTEN(D);

J = FILTER F BY idofdaysel == idoftheday;

DUMP J;

Данные во втором примере (дата примечания уже в формате Unix): у вас есть файл требований, например:

1, 'ctr1', 1359460800000
2, 'ctr2', 1354363200000

У вас есть файл операций, например: idope, labelope, dateope, idoftheday, infope.

'ctr0','toto',1359460800000,1,'blabla0'
'ctr0','tata',1359460800000,2,'blabla1'
'ctr1','toto',1359460800000,1,'blabla2'
'ctr1','tata',1359460800000,2,'blabla3'
'ctr2','toto',1359460800000,1,'blabla4'
'ctr2','tata',1359460800000,2,'blabla5'
'ctr3','toto',1359460800000,1,'blabla6'
'ctr3','tata',1359460800000,2,'blabla7'

Результат должен быть таким:

1, 'ctr1', 'tata',1359460800000,2,'blabla3'
2, 'ctr2', 'toto',1359460800000,1,'blabla4'

person jagwar    schedule 15.04.2013    source источник


Ответы (1)


Примеры ввода и вывода очень помогли бы, но из того, что вы опубликовали, мне кажется, что проблема не столько в написании сценария Pig, сколько в определении того, чего именно вы надеетесь достичь. Мне непонятно, зачем вы вообще группируетесь. Какова цель группировки по адресу, например?

Вот как бы я решил вашу проблему:

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

scored = FOREACH A GENERATE *, money / POW(1+ABS($my_age-age)/10, 2) AS score;
ordered = ORDER scored BY score DESC;
top10 = LIMIT ordered 10;

Это дает вам 10 лучших людей в соответствии с вашей функцией оптимизации.

Тогда остается только разработать функцию, соответствующую вашим собственным суждениям. Например, в выбранной мной функции человек вашего возраста со 100 000 долларов США будет предпочтительнее человека с 350 000 долларов США, который на 10 лет старше (или моложе). Но кто-то с 500 000 долларов, который на 20 лет старше или моложе, предпочтительнее, чем кто-то вашего возраста, у которого всего 50 000 долларов. Если что-то из этого не соответствует вашей интуиции, измените формулу. Скорее всего, простого квадратичного множителя будет недостаточно. Но, немного поэкспериментировав, вы можете найти то, что вам подходит.

person reo katoa    schedule 16.04.2013
comment
Большое спасибо, ваш ответ очень интересен, но он не решает мою проблему. Я изменю пример. - person jagwar; 16.04.2013