2012-03-28 30 views
46

Ich habe so etwas wie dies die Anzahl der Zeilen in einem Alias ​​in PIG zu zählen:PIG, wie eine Anzahl von Zeilen in alias zählen

logs = LOAD 'log' 
logs_w_one = foreach logs generate 1 as one; 
logs_group = group logs_w_one all; 
logs_count = foreach logs_group generate SUM(logs_w_one.one); 
dump logs_count; 

Dies zu ineffizient zu sein scheint. Bitte erleuchte mich, ob es einen besseren Weg gibt!

Antwort

90

COUNT ist ein Teil von Schwein see the manual

LOGS= LOAD 'log'; 
LOGS_GROUP= GROUP LOGS ALL; 
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT(LOGS); 
+2

Ist es möglich, die Anzahl der Zeilen in einem Alias ​​ohne erste Gruppierung zu zählen? – zzz

+2

Gleiche Frage. Ich habe gelesen, dass 'GROUP x ALL 'eine Serialisierung in der Pipeline erzwingt, was zu einer möglichen Verlangsamung führen kann. Ist das korrekt? –

+0

Sie müssen vor dem Zählen gruppieren. Laut http://pig.apache.org/docs/r0.15.0/func.html#count: "COUNT benötigt eine vorangehende GROUP ALL-Anweisung für globale Zählungen und eine GROUP BY-Anweisung für Gruppenzählungen." –

29

Seien Sie vorsichtig, mit COUNT Ihrem ersten Elemente in der Tasche nicht null sein muss. Andernfalls können Sie die Funktion COUNT_STAR verwenden, um alle Zeilen zu zählen.

29

Arnon Rotem-Gal-Oz hat diese Frage schon vor einiger Zeit beantwortet, aber ich dachte, einige mögen diese etwas prägnantere Version mögen.

LOGS = LOAD 'log'; 
LOG_COUNT = FOREACH (GROUP LOGS ALL) GENERATE COUNT(LOGS); 
0

Hier ist eine Version mit Optimierung. Alle oben genannten Lösungen erfordern würde Schwein voll Tupel lesen und schreiben, wenn das Zählen, das Skript unten nur schreiben ‚1'-s

DEFINE row_count(inBag, name) RETURNS result { 
    X = FOREACH $inBag generate 1; 
    $result = FOREACH (GROUP X ALL PARALLEL 1) GENERATE '$name', COUNT(X); 
}; 

Die Verwendung es wie

xxx = row_count(rows, 'rows_count'); 
4

Grundzählung erfolgt wie in anderen Antworten, und in der Schweine Dokumentation wurde festgestellt:

logs = LOAD 'log'; 
all_logs_in_a_bag = GROUP logs ALL; 
log_count = FOREACH all_logs_in_a_bag GENERATE COUNT(logs); 
dump log_count 

Sie haben Recht, dass das Zählen ineffizient ist, auch wenn Schweine gebautet COUNT verwenden, da dies wird u se ein Reduzierstück. Wie auch immer, ich hatte heute eine Enthüllung, dass einer der Wege, es zu beschleunigen, darin bestehen würde, die RAM-Nutzung der Beziehung, die wir zählen, zu reduzieren.

Mit anderen Worten, wenn wir eine Beziehung zählen, kümmern wir uns nicht wirklich um die Daten selbst, also verwenden wir so wenig RAM wie möglich. Sie waren mit Ihrer ersten Iteration des Count-Skripts auf dem richtigen Weg.

logs = LOAD 'log' 
ones = FOREACH logs GENERATE 1 AS one:int; 
counter_group = GROUP ones ALL; 
log_count = FOREACH counter_group GENERATE COUNT(ones); 
dump log_count 

Dies funktioniert auf viel größere Beziehungen als das vorherige Skript und sollte viel schneller sein. Der Hauptunterschied zwischen diesem und Ihrem ursprünglichen Skript besteht darin, dass wir nichts zusammenfassen müssen.

0

Was Sie wollen, ist die Linien alle in einer Beziehung zu zählen (Daten-Set in Pig Latin)

Dies ist sehr einfach im Anschluss an die nächsten Schritte:

logs = LOAD 'log'; --relation called logs, using PigStorage with tab as field delimiter 
logs_grouped = GROUP logs ALL;--gives a relation with one row with logs as a bag 
number = FOREACH LOGS_GROUP GENERATE COUNT_STAR(logs);--show me the number 

ich zu sagen habe ist es wichtig, Kevins Wenn wir COUNT anstelle von COUNT_STAR verwenden, hätten wir nur die Anzahl der Zeilen, deren erstes Feld nicht null ist.

Auch ich mag Jeromes Ein-Zeilen-Syntax ist es prägnanter, aber um didaktisch zu sein, ziehe ich es vor, es in zwei Teile zu teilen und einen Kommentar hinzuzufügen.

Im Allgemeinen ziehe ich:

numerito = FOREACH (GROUP CARGADOS3 ALL) GENERATE COUNT_STAR(CARGADOS3); 

über

name = GROUP CARGADOS3 ALL 
number = FOREACH name GENERATE COUNT_STAR(CARGADOS3); 
2

USE COUNT_STAR

LOGS= LOAD 'log'; 
LOGS_GROUP= GROUP LOGS ALL; 
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT_STAR(LOGS); 
Verwandte Themen