2012-03-01 25 views
4

我用豬進行數據準備和我面對這似乎很容易出現問題,但我不能處理:如何在豬身上產生一個行號?

例如,我有名字

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

那麼何來的一列我爲每個名字添加一個行號?結果會是這樣的:

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

感謝您閱讀此問題!

回答

3

不幸的是,沒有辦法枚舉Pig Latin中的行。至少,我找不到一個簡單的方法。一種解決方案是使用單個Reduce任務實現單獨的MapReduce作業,該任務執行實際枚舉。更確切地說,

映射階段:將所有行分配給相同的鍵。 Single Reduce任務:接收帶有迭代器的所有行的單個鍵。由於reduce任務只會在一臺物理機器上運行,而「reduce function」只會被調用一次,所以函數內部的本地計數器可以解決問題。

如果數據龐大且無法在單個reduce機器上處理,則可以使用主節點上的默認MapReduce計數器。

+0

謝謝Shatlyk,我沒有發現豬拉丁既不的方式。是的,只使用1個reduce節點的想法可以解決這個問題,但它不是一個真正的並行算法 – Breakinen 2012-07-21 15:24:22

+0

由於reducer需要處理與整個mapper輸入大小相同的數據,所以它會成爲一個瓶頸map-reduce程序。我覺得很難實現這樣一個真正的並行程序,因爲tasktrackers不能維護全局變量^^ BTW,最後我通過在單個機器上使用java程序解決了這個問題,它的速度很快:) – Breakinen 2012-07-21 15:31:41

+0

好吧,在我的情況下,「枚舉部分」是一小步。單臺減速機花了很長時間,但它是由其他步驟占主導地位。 – 2012-07-23 13:24:03

1

草圖的想法,假設我們要排序的「名稱」列是數字而不是字符串。 也假設很好的非偏態分佈。

  1. WITH_GROUPS = foreach TABLE生成名稱,名稱/ 100作爲group_id;
  2. group WITH_GROUPS by group_id;
  3. PER_GROUP =生成組,count(*);
  4. ACCUM_PER_GROUP =將PER_GROUP與其自身交叉連接,計算每個組的累計計數;
  5. cogroup ACCUM_PER_GROUP with WITH_GROUPS by group_id;
  6. 在減速運行指定每行從該組accumulative_count
10

豬開始的ID沒有一個機制來做到這一點,當你問這個問題一個UDF。但是,Pig 0.11引入了可用於此目的的RANK operator

1

@cabad

在它看來,RANK運營商的工作,但你不能保證有越來越多的行ID不會對您的數據提供了一些限制表面。

問題來自提供給排名運算符的任何行,它們將相同的排名相同。如果你能夠保證沒有兩行有相同的字段用於排名,那麼這種方法可能會奏效,但我想我會把它放在「方形釘圓孔」方法中。

見這個例子從[文檔] 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)     
+0

對於OP描述的用例,簡單的RANK A;會工作。 – cabad 2014-03-17 03:20:42