Какой может быть процедура/код для удаления строкового выражения из файла с помощью Apache Pig?

A = load '/home/wrdtest.txt';

B = foreach A generate flatten(TOKENIZE((chararray)$0)) as word;

C = filter B by word != 'the';

D = group C by word;

E = foreach D generate COUNT(C) as count, group as word;

F = order E by count desc;

store F into '/tmp/sample_data20';

Я просто хочу отфильтровать текст. Третий шаг фильтрует текст и удаляет «the» из текстового файла. Но я хочу удалить из текста набор из 499 слов (стоп-слов). Я пытался использовать '|' (как ИЛИ) как:

C = filter B by word != 'the|and|or'...but it didnt work.

Не могли бы вы предложить это, и могу ли я включить текстовый файл, например (stopwords.txt), чтобы удалить стоп-слова.

Я наивный пользователь Свиньи


person Debaditya    schedule 11.01.2012    source источник


Ответы (2)


Что-то вроде удаления стоп-слов настолько сложно, что этого не будет во встроенных функциях. Вам потребуется написать определяемую пользователем функцию, что довольно просто сделать.

-- load the data line by line
lines = LOAD 'datafile.txt' USING TextLoader() AS (line:chararray);

-- apply some sort of UDF that returns the exact line without the stop words
nostop = FOREACH lines GENERATE myudfs.removestop(line);

-- store the data out
STORE nonstop INTO 'datafile_nostop.txt';

Толкнуть этот список в задачи — это совсем другая история. Если список относительно небольшой, порядка тысяч, вы можете запечь стоп-слова в свой код (т. е. жестко закодировать список), чтобы он был доступен. В противном случае вы можете использовать распределенный кэш для отправки файла.


Имея больше информации, которую вы предоставили, я могу предложить альтернативный подход. Однако мой описанный выше подход к использованию UDF все еще действителен.

Этот новый подход будет включать в себя загрузку другого файла, а затем эффективное выполнение антисоединения для удаления элементов, соответствующих списку. Вы должны убедиться, что stopwords.txt имеет одно слово в строке, чтобы это работало. Чтобы выполнить анти-объединение (т. е. оставить в списке то, что не соответствует другому списку), я сделаю левое внешнее соединение (используя replicated), затем отфильтруйте, где столбец стоп-слов пуст (т. е. у него нет совпадающего стоп-слова).

A = load '/home/wrdtest.txt';

-- load the stop words list
SW = load '/home/stopwords.txt' as (stopword:chararray);    

B = foreach A generate flatten(TOKENIZE((chararray)$0)) as word;

-- join the data with a left outer join
-- using replicated should be done with the right relation (SW) is small
SW2 = join B by word LEFT OUTER, SW by stopword USING 'replicated';

-- filter out where the stopword is null, meaning it is not in the stopword list
C = filter SW2 by stopword IS NULL;

-- remove the stopword column that we don't need.
C = foreach C generate word;

D = group C by word;

E = foreach D generate COUNT(C) as count, group as word;

F = order E by count desc;

store F into '/tmp/sample_data20';
person Donald Miner    schedule 11.01.2012
comment
Пожалуйста, предложите мне последнее редактирование, которое я сделал в резюме. Я предоставил код, над которым сейчас работаю. - person Debaditya; 12.01.2012
comment
Я выполнил код. Но результаты, кажется, те же. Моя структура stopwords.txt представляет собой... одно слово в строке. - person Debaditya; 12.01.2012

Я использовал приведенное выше решение Дональда Майнера.

Я изменил отношение к части JOIN следующим образом.

SW2 = join B by word LEFT, SW by stopword;

и работает для меня.

person Haile    schedule 25.08.2013