Свинья, как посчитать количество строк в псевдониме - PullRequest
48 голосов
/ 28 марта 2012

Я сделал что-то подобное, чтобы подсчитать количество строк в псевдониме в 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 ]

94 голосов
/ 28 марта 2012

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

LOGS= LOAD 'log';
LOGS_GROUP= GROUP LOGS ALL;
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT(LOGS);
29 голосов
/ 28 марта 2014

Арнон Ротем-Гал-Оз уже ответил на этот вопрос некоторое время назад, но я подумал, что некоторым может понравиться эта несколько более краткая версия.

LOGS = LOAD 'log';
LOG_COUNT = FOREACH (GROUP LOGS ALL) GENERATE COUNT(LOGS);
29 голосов
/ 28 марта 2012

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

4 голосов
/ 13 января 2016

Основной подсчет производится, как указано в других ответах и ​​в документации на свиней:

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

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

2 голосов
/ 27 февраля 2016

USE COUNT_STAR

LOGS= LOAD 'log';
LOGS_GROUP= GROUP LOGS ALL;
LOG_COUNT = FOREACH LOGS_GROUP GENERATE COUNT_STAR(LOGS);
0 голосов
/ 26 февраля 2016

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

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

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 у нас будет только количество строк, первое поле которых не равно нулю.

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

В общем, я предпочитаю:

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

, а не

name = GROUP CARGADOS3 ALL
number = FOREACH name GENERATE COUNT_STAR(CARGADOS3);
0 голосов
/ 13 августа 2015

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