2012-03-28 13 views
46

ho fatto qualcosa di simile per contare il numero di righe in un alias in PIG:PIG come contare un numero di righe alias

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; 

Questo sembra essere troppo inefficiente. Per favore mi illumini se c'è un modo migliore!

risposta

90

COUNT fa parte del maiale see the manual

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

è possibile contare il numero di righe in un alias senza prima raggruppamento? – zzz

+2

Stessa domanda. Ho letto che 'GROUP x ALL' costringerà una serializzazione nella pipeline con il conseguente possibile rallentamento. È corretto? –

+0

Devi raggruppare prima del conteggio. Secondo http://pig.apache.org/docs/r0.15.0/func.html#count: "COUNT richiede un'istruzione GROUP ALL precedente per i conteggi globali e un'istruzione GROUP BY per i conteggi di gruppo." –

29

Attenzione, con COUNT il vostro primo oggetto nella borsa non deve essere nullo. Altrimenti puoi utilizzare la funzione COUNT_STAR per contare tutte le righe.

29

Arnon Rotem-Gal-Oz ha già risposto a questa domanda qualche tempo fa, ma ho pensato che alcuni potrebbero apprezzare questa versione leggermente più concisa.

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

Ecco una versione con ottimizzazione. Tutte le soluzioni di cui sopra richiederebbe maiale a leggere e scrivere piena tuple durante il conteggio, questo script di seguito basta scrivere '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); 
}; 

L'uso è come

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

conteggio di base è fatto come lo afferma in altre risposte, e nella documentazione maiale:

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 

Hai ragione che il conteggio è inefficiente, anche quando si utilizza COUNT incorporato di maiale, perché questo sarà u se un riduttore. Tuttavia, oggi ho avuto una rivelazione che uno dei modi per accelerarlo sarebbe ridurre l'utilizzo della RAM della relazione che stiamo contando.

In altre parole, quando si conta una relazione, non ci interessa realmente i dati stessi, quindi usiamo la quantità di RAM minima possibile. Sei stato sulla strada giusta con la tua prima iterazione dello script di conteggio.

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 

Questo funzionerà su relazioni molto più grandi rispetto allo script precedente e dovrebbe essere molto più veloce. La principale differenza tra questo e il tuo script originale è che non abbiamo bisogno di sommare nulla.

0

Quello che vuoi è quello di contare tutte le linee in una relazione (dataset in Pig Latin)

Questo è molto semplice seguendo i passi successivi:

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 

che ho da dire è importante Kevin indicare come utilizzando COUNT anziché COUNT_STAR avremmo solo il numero di righe il cui primo campo non è nullo.

Anche a me la sintassi di una riga di Jerome è più concisa ma per essere didattica preferisco dividerla in due e aggiungere qualche commento.

In generale preferisco:

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

oltre

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

USO COUNT_STAR

LOGS= LOAD 'log'; 
LOGS_GROUP= GROUP LOGS ALL; 
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT_STAR(LOGS); 
Problemi correlati