在猪我想减少组有1个元素具有优先权的特定类型

时间:2016-04-13 23:18:32

标签: hadoop apache-pig

在猪中,我有A,B,C,id,id_type列。可能的id_types是“zip”,“city”,“county”,“state”和“country”。

我希望这样做,以便每个现有的A,B,C只存在一个实例,但优先使用id_type“zip”的行,但如果不是“zip”,那么“city”,如果不是“城市”,而是......等等。

所以,如果我有以下两行

(a, b, c, 555, city)
(a, b, c, 123, state)

我想删除第二个。我可以通过A,B,C分组来获得

({a, b, c}, {(a, b, c, 555, city), (a, b, c, 123, state)})

但我不知道如何从$ 1中删除所有不需要的元素

3 个答案:

答案 0 :(得分:0)

@inquistive_mind:我使用以下输入运行您的代码并且它不会返回OP提出的内容

输入:

(aa,bb,cc,1,zip)
(aa,bb,cc,2,street)
(mmm,nnn,cc,3,county)
(mmm,nnn,cc,4,zip)
(mmm,nnn,cc,5,state)
(lll,ccc,ddd,6,city)
(lll,ccc,xxx,7,country)

运行代码后的输出:

((aa,bb,cc),{(2,country),(1,zip)})
((lll,ccc,ddd),{(6,city)})
((lll,ccc,xxx),{(7,country)})
((mmm,nnn,cc),{(5,state),(4,zip),(3,county)})

您清楚地看到它不会只保留id_type优先级的一个条目。

答案 1 :(得分:0)

我使用PYTHON UDF解决了这个问题。如果有更好的方法请告诉我

Python代码保存为priority.py

def unique_list(input):
    my_list = input
    last_list = []
    #print(my_list[0][4])
    #print(len(my_list))
    for i in range(len(my_list)):
        last_list.append(my_list[i][4])


        print(last_list)
        for j in range(len(last_list)):
          if(last_list[j]) == "zip":
             return_list = list(my_list[j])
             break
          elif (last_list[j] == 'city'):
              return_list = list(my_list[j])
              break
          elif (last_list[j] == 'county'):
              return_list = list(my_list[j])
              break
          elif (last_list[j] == 'state'):
              return_list = list(my_list[j])
              break
          elif (last_list[j] == 'country'):
              return_list = list(my_list[j])
              break

 return return_list

现在的猪代码

REGISTER 'priority.py' using jython as callme
A = LOAD 'addr.dat' USING PigStorage(',') AS (A : chararray, B :chararray , C:  chararray , ID :  chararray,  ID_TYPE :  chararray);

B = DISTINCT A;
Z=  GROUP B BY (A,B,C);
O = FOREACH Z GENERATE callme.unique_list($1) as record :{(A : chararray, B :chararray , C:  chararray , ID :  chararray,  ID_TYPE :  chararray)} ;
DUMP O;

请针对您的输入执行此操作并检查其是否有效

答案 2 :(得分:0)

一种方法是编写UDF,另一种方法是:

 ABC = load 'testdata.csv' using PigStorage(',') as (a: chararray, b: chararray, c: chararray, id: int, id_type: chararray);
MappedABC = foreach ABC generate a, b, c, id, id_type, (id_type == 'zip' ? 1 : (id_type == 'city' ?  2 : (id_type == 'county' ?  3 : (id_type == 'state' ?  4 : 5)))) as idorder;
FinalABC = foreach (group MappedABC by (a,b,c)) {
    OrderedABC = order MappedABC by idorder;
    LimitedABC = limit OrderedABC 1;
    generate
        flatten(LimitedABC)
    ;

};
store FinalABC into 'out' using PigStorage(';');