2012-03-28 65 views
46

hice algo como esto para contar el número de filas en un alias en PIG:PIG cómo contar un número de filas de 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; 

Ésta parece ser demasiado ineficiente. ¡Por favor, ilumíname si hay una mejor manera!

Respuesta

90

COUNT es parte de cerdo see the manual

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

¿Es posible contar el número de filas en un alias sin antes agrupación? – zzz

+2

La misma pregunta. Leí que 'GROUP x ALL' forzará una serialización en la tubería con la consiguiente desaceleración posible. ¿Es eso correcto? –

+0

Tienes que agrupar antes de contar. De acuerdo con http://pig.apache.org/docs/r0.15.0/func.html#count: "COUNT requiere una declaración anterior GROUP ALL para conteos globales y una declaración GROUP BY para conteos grupales". –

29

tener cuidado, con COUNT su primer artículo en la bolsa no debe ser nulo. De lo contrario, puede usar la función COUNT_STAR para contar todas las filas.

29

Arnon Rotem-Gal-Oz ya respondió esta pregunta hace un tiempo, pero pensé que a algunos les podría gustar esta versión un poco más concisa.

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

Aquí hay una versión con optimización. Todas las soluciones anteriores requerirían de cerdo a leer y escribir tupla completa cuando se cuentan, esta secuencia de comandos a continuación simplemente escribir '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); 
}; 

El uso como si fuera

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

conteo básico se hace como se ha dicho en otras respuestas, y en la documentación de cerdo:

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 

Tienes razón en que el recuento es ineficiente, incluso cuando se utiliza COUNT orden interna de cerdo, ya que esto u se un reductor Sin embargo, hoy tuve la revelación de que una de las formas de acelerarlo sería reducir la utilización de RAM de la relación que estamos contando.

En otras palabras, al contar una relación, en realidad no nos importan los datos en sí, así que usemos la menor cantidad de RAM posible. Estabas en el camino correcto con tu primera iteración del script de conteo.

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 

Esto funcionará en relaciones mucho más grandes que el script anterior y debería ser mucho más rápido. La principal diferencia entre esto y su script original es que no necesitamos sumar nada.

0

Lo que queremos es contar todas las líneas en una relación (conjunto de datos en latín de cerdo)

Esto es muy sencillo siguiendo los siguientes pasos:

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 

que tengo que decir es importante Kevin Como usar COUNT en lugar de COUNT_STAR, solo tendremos el número de líneas cuyo primer campo no es nulo.

También me gusta la sintaxis de una línea de Jerome, es más conciso, pero para ser didáctico, prefiero dividirlo en dos y agregar algún comentario.

En general prefiero:

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

sobre

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); 
Cuestiones relacionadas