如何在猪中生成行号?

时间:2012-03-01 02:26:13

标签: hadoop apache-pig

我正在使用猪进行数据准备,我遇到了一个似乎很容易但我无法处理的问题:

例如,我有一列名称

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

然后如何为每个名称添加行号?结果将是这样的:

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

感谢您阅读此问题!

4 个答案:

答案 0 :(得分:10)

当你提出这个问题时,猪没有机制这样做。然而,Pig 0.11引入了RANK operator可用于此目的。

答案 1 :(得分:3)

不幸的是,没有办法在Pig Latin中枚举行。至少,我找不到一个简单的方法。一种解决方案是使用单个Reduce任务实现单独的MapReduce作业,该任务执行实际枚举。更确切地说,

映射阶段:将所有行分配给相同的键。 单个Reduce任务:使用迭代器接收所有行的单个键。由于reduce任务只在1台物理机器上运行,“reduce function”只调用一次,因此函数内的局部计数器可以解决问题。

如果数据量很大且无法在单个reduce机器上处理,则可以使用主节点上的默认MapReduce计数器。

答案 2 :(得分:1)

草图的想法,假设我们要排序的“名称”列是数字而不是字符串。 还假设有很好的非倾斜分布。

  1. WITH_GROUPS = foreach TABLE生成名称,name / 100为group_id;
  2. group_id组的WITH_GROUPS;
  3. PER_GROUP =生成组,计数(*);
  4. ACCUM_PER_GROUP =与自身交叉加入PER_GROUP,计算每组的累计次数;
  5. cogroup ACCUM_PER_GROUP with WITH_GROUPS by group_id;
  6. reducer中的
  7. 运行一个UDF,为每个行分配一个从该组开始的id accumulative_count

答案 3 :(得分:1)

@cabad

从表面上看,似乎RANK运算符可以正常工作,但不保证在不对数据提供某些约束的情况下增加行ID。

问题来自提供给排名运营商的任何等于相同排名的行。如果你能够保证没有两行有相同的字段用于排名,那么这种方法可能有用,但我想我会把它放在“方形钉圆孔”的方法中。

从[docs] 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)