PIG как подсчитать количество строк в alias
Я сделал что-то вроде этого, чтобы подсчитать количество строк в псевдониме в 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;
Это кажется слишком неэффективным. Пожалуйста, просветите меня, если есть лучший путь!
7 ответов
COUNT является частью свиньи посмотреть инструкцию
LOGS= LOAD 'log';
LOGS_GROUP= GROUP LOGS ALL;
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT(LOGS);
будьте осторожны, с COUNT
ваш первый предмет в сумке не должен быть нулевым. Иначе вы можете использовать функцию COUNT_STAR
для подсчета всех строк.
Арнон Ротем-Гал-Оз уже ответил на этот вопрос некоторое время назад, но я подумал, что некоторым может понравиться эта немного более краткая версия.
LOGS = LOAD 'log';
LOG_COUNT = FOREACH (GROUP LOGS ALL) GENERATE COUNT(LOGS);
основной подсчет делается так, как было указано в других ответах, и в документации свиньи:
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
Вы правы, что подсчет неэффективен, даже при использовании встроенного подсчета свиньи, потому что это будет использовать один редуктор. Однако сегодня у меня было откровение, что одним из способов ускорить его было бы уменьшить использование ОЗУ отношения, которое мы подсчитываем.
другими словами, при подсчете отношения мы фактически не заботимся о самих данных, поэтому давайте использовать как маленький баран, насколько это возможно. Вы были на правильном пути с вашей первой итерации графа сценария.
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
это будет работать на гораздо больших отношениях, чем предыдущий скрипт, и должно быть намного быстрее. Основное различие между этим и вашим оригинальным сценарием заключается в том, что нам не нужно ничего суммировать.
ИСПОЛЬЗУЙТЕ COUNT_STAR
LOGS= LOAD 'log';
LOGS_GROUP= GROUP LOGS ALL;
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT_STAR(LOGS);
вот версия с оптимизацией. Все решения выше потребовали бы, чтобы свинья читала и писала полный кортеж при подсчете, этот скрипт ниже просто пишет " 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');
то, что вы хотите, это подсчитать все строки в отношении (dataset в 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 вместо COUNT_STAR, у нас было бы только количество строк, первое поле которых не равно null.
также мне нравится синтаксис одной строки Джерома, он более лаконичен, но для того, чтобы быть дидактическим, я предпочитаю разделить его на два и добавить комментарий.
In генерал я предпочитаю:
numerito = FOREACH (GROUP CARGADOS3 ALL) GENERATE COUNT_STAR(CARGADOS3);
над
name = GROUP CARGADOS3 ALL
number = FOREACH name GENERATE COUNT_STAR(CARGADOS3);