Подтвердить что ты не робот

PIG, как подсчитать количество строк в псевдониме

Я сделал что-то подобное, чтобы подсчитать количество строк в псевдониме в PIG:

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;

Это кажется слишком неэффективным. Пожалуйста, просветите меня, если есть лучший способ!

4b9b3361

Ответ 1

COUNT является частью свиньи см. руководство

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

Ответ 2

Будьте осторожны, COUNT ваш первый элемент в сумке не должен быть пустым. Кроме того, вы можете использовать функцию COUNT_STAR для подсчета всех строк.

Ответ 3

Арнон Ротем-Гал-Оз уже ответил на этот вопрос некоторое время назад, но я подумал, что некоторым может понравиться эта чуть более сжатая версия.
LOGS = LOAD 'log';
LOG_COUNT = FOREACH (GROUP LOGS ALL) GENERATE COUNT(LOGS);

Ответ 4

Базовый подсчет выполняется, как указано в других ответах, и в документации на свиньи:

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

Вы правы, что подсчет неэффективен, даже при использовании свиньи, встроенной в COUNT, потому что это будет использовать один редуктор. Тем не менее, сегодня у меня было откровение, что одним из способов ускорить его было бы сократить использование ОЗУ отношения, которое мы рассчитываем.

Другими словами, при подсчете отношения мы фактически не заботимся о самих данных, поэтому давайте использовать как можно меньше ОЗУ. Вы были на правильном пути со своей первой итерацией счетчика script.

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

Это будет работать с гораздо большими отношениями, чем предыдущий script, и должно быть намного быстрее. Основное различие между этим и вашим оригинальным script заключается в том, что нам не нужно ничего суммировать.

Ответ 5

ИСПОЛЬЗОВАТЬ COUNT_STAR

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

Ответ 6

Вот версия с оптимизацией. Все вышеприведенные решения потребовали бы, чтобы свиньи читали и записывали полный кортеж при подсчете, этот script ниже просто записывает '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);
};

Использовать его как

xxx = row_count(rows, 'rows_count');

Ответ 7

То, что вы хотите, - это подсчет всех строк в отношении (набор данных на языке Pig Latin)

Это очень легко после следующих шагов:

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

Я должен сказать, что важно, чтобы Кевин указывал, что вместо COUNT_STAR используется COUNT, у нас будет только количество строк, первое поле которых не является нулевым.

Также мне нравится синтаксис одной строки Джерома, он более краткий, но для того, чтобы быть дидактическим, я предпочитаю разделить его на две части и добавить комментарий.

В целом я предпочитаю:

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

над

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