2016-04-24 2 views
1

У меня есть большое количество строк в каком-то текстовом файле и вам нужно преобразовать эти строки таким алгоритмом: преобразовать строку в нижний регистр и удалить все пробелы.Hadoop MapReduce пример преобразования строки

Можете ли вы привести пример функции Hadoop MapReduce, которая реализует этот алгоритм?

спасибо.

+0

Вы попробовали что-нибудь? –

+1

Я нашел несколько примеров, которые показывают, как агрегировать значения по ключам. Например, подсчитайте количество слов в тексте ввода. Мне интересно, есть ли возможность преобразования входных строк вместо вычисления совокупных значений с помощью процедур mapreduce. Это обычная практика, или это не лучшее решение делать такие вещи с уменьшением карты? Я не прошу сделать эту работу для меня, но мне нужен простой пример и подтверждение того, что я в правильном направлении –

ответ

0

Я пробовал приведенный ниже код и получал вывод в одной строке.

общественного класса TOUPPER {

public static class textMapper extends Mapper<LongWritable,Text,NullWritable,Text> 
{ 
    Text outvalue=new Text(); 

    public void map(LongWritable key,Text values,Context context) throws IOException, InterruptedException 
    { 
     String token; 
     StringBuffer br=new StringBuffer(); 
     StringTokenizer st=new StringTokenizer(values.toString()); 
     while(st.hasMoreTokens()) 
     { 
      token=st.nextToken(); 
      br.append(token.toUpperCase()); 
     } 
     st=null; 
     outvalue.set(br.toString()); 
     context.write(NullWritable.get(), outvalue); 
     br=null; 

    } 
} 
public static class textReduce extends Reducer<NullWritable,Text,NullWritable,Text> 
{ 
    Text outvale=new Text(); 
    public void reduce(NullWritable key,Iterable<Text> values,Context context) throws IOException, InterruptedException 
    { 
     StringBuffer br=new StringBuffer(); 
     for(Text st:values) 
     { 
      br.append(st.toString()); 
     } 
     outvale.set(br.toString()); 
     context.write(NullWritable.get(), outvale); 
    } 
} 
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { 
    Configuration conf=new Configuration(); 
    @SuppressWarnings("deprecation") 
    Job job=new Job(conf,"touipprr"); 

    job.setJarByClass(toUpper.class); 
    job.setMapperClass(textMapper.class); 
    job.setReducerClass(textReduce.class); 

    job.setOutputKeyClass(NullWritable.class); 
    job.setOutputValueClass(Text.class); 

    FileInputFormat.addInputPath(job, new Path(args[0])); 
    FileOutputFormat.setOutputPath(job, new Path(args[1])); 

    System.exit(job.waitForCompletion(true)?1:0); 




} 

}

0


В те дни, когда я играл с картой-свертка, у меня была подобная мысль, что должна быть некоторая практика или метод, с помощью которого мы можем модифицировать каждое слово в записи и делать все чистящие средства.
Когда мы перечислим весь алгоритм сокращения карты, у нас есть функция отображения, которая разбивает поступающие записи на токены с помощью разделителей (возможно, вы узнаете о них лучше). Теперь попробуем подойти к описанию проблемы, данному вами описательным образом.
Ниже перечислены вещи, которые я буду стараться делать, когда я новичок в Map-Reduce:

> I will probably write a map() method which will split the lines for me 
> I will possibly run out of options and write a reduce function 
and somehow will be able to achieve my objective 

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

В таких ситуациях, в которые входит ваша проблема, класс пришел мне на помощь: ChainMapper Теперь, как работает ChainMapper? следующие несколько пунктов, которые следует учитывать


-> Первый картограф будет считывать файл с HDFS, разбивать каждую строку в соответствии с разделителем и хранить токены в контексте.
-> Второй преобразователь получит выход из первого картографа и здесь вы можете сделать все виды операций, связанных строк, как вы бизнес требует, такие как шифрование текста или изменения в верхний регистр или нижний регистр и т.д.
-> Управляемая строка, которая является результатом второго преобразователя, должна быть снова сохранена в контексте
-> Теперь, если вам нужен редуктор для выполнения задачи агрегации, такой как wordcount, для этого.

У меня есть код, который может быть неэффективным (или некоторые из них могут чувствовать себя ужасно), но он служит вашей цели, как вы могли бы играть с mapreduce.

SplitMapper.java

public class SplitMapper extends Mapper<LongWritable,Text,Text,IntWritable>{ 
    @Override 
    public void map(Object key,Text value,Context context) 
            throws IOException,InterruptedException{ 
     StringTokenizer xs=new StringTokenizer(value.toString()); 
     IntWritable dummyValue=new IntWritable(1); 
     while(xs.hasMoreElements()){ 
      String content=(String)xs.nextElement(); 
      context.write(new Text(content),dummyValue); 
     } 
    } 
} 


LowerCaseMapper.Java

public class LowerCaseMapper extends Mapper<Text,IntWritable,Text,IntWritable>{ 
    @Override 
    public void map(Text key,IntWritable value,Context context) 
             throws IOException,InterruptedException{ 
     String val=key.toString().toLowerCase(); 
     Text newKey=new Text(val); 
     Context.write(newKey,value);  
    } 
} 

Поскольку я выступаю в WordCount вот так я требую редуктора

ChainMapReducer.java

public class ChainMapReducer extends Reducer<Text,IntWritable,Text,IntWritable>{ 
    @Override 
    public void reduce(Text key,Iterable<IntWritable> value,Context context) 
           throws IOException,InterruptedException{ 
     int sum=0; 
     for(IntWritable v:value){ 
      sum+=value.get(); 
     } 
     context.write(key,new IntWritables(sum)); 
    } 
} 

Чтобы иметь возможность реализовать концепцию chainmapper успешно, вы должны обратить внимание на все детали класса водителя

DriverClass.java

public class DriverClass extends Configured implements Tool{ 
    static Configuration cf; 
    public int run(String args[]) throws IOException,InterruptedException,ClassNotFoundException{ 
     cf=new Configuration(); 
     Job j=Job.getInstance(cf); 
     //configuration for the first mapper 
     Configuration.splitMapConfig=new Configuration(false); 
     ChainMapper.addMapper(j,SplitMapper.class,Object.class,Text.class,Text.class,IntWritable.class,splitMapConfig); 
     //configuration for the second mapper 
     Configuration.lowerCaseConfig=new Configuration(false); 
     ChainMapper.addMapper(j,LowerCaseMapper.class,Text.class,IntWritable.class,Text.class,IntWritable.class,lowerCaseConfig); 

     j.setJarByClass(DriverClass.class); 
     j.setCombinerClass(ChainMapReducer.class); 
     j.setOutputKeyClass(Text.class); 
     j.setOutputValueClass(IntWritable.class); 

     Path outputPath=new Path(args[1]); 
     FileInputFormat.addInputPath(j,new Path(args[0])); 
     FileOutputFormat.setOutputPath(j,outputPath); 
     outputPath.getFileSystem(cf).delete(outputPath,true); 
    } 
    public static void main(String args[]) throws Exception{ 
     int res=ToolRunner.run(cf,new DriverClass(),args); 
     System.exit(1); 
    } 
} 

Класс драйвера довольно много понятно, только нужно соблюдать подпись ChainMapper.add(<job-object>,<Map-ClassName>,<Input arguments types>,<configuration-for-the-concerned-mapper>)

Я надеюсь, что решение служит вашей цели, пожалуйста, дайте мне знать в случае возникновения каких-либо проблем, которые могут возникнуть при попытке реализовать.
Thankyou!

+0

, вы можете удалить ненужные пространства, используя метод trim() во втором сопоставлении, который является самой LoweCaseMapper.java ! –

Смежные вопросы