[MapReduce]通信データのクリーニング処理



MapReduce通信データのクリーニング処理

これで、関係者の通信データのコピーが取得され、データは単純に前処理されて統合され、最終的に出力されます。

要求する:

  1. 電話番号を大人の名前に置き換えます
  2. 通話の発信と受信のタイムスタンプを日付に変換します
  3. 通話時間を秒単位で確認します
  4. 州コードを州名に置き換えます

データセット::
ここに画像の説明を挿入します
phone発信者の携帯電話番号、受信者の携帯電話番号、開始タイムスタンプ、受け入れタイムスタンプ、発信者アドレス州コード、受信者アドレス州コード
city:アドレスID、州コード、州名
person:電話ID、電話番号、名前

ここに画像の説明を挿入します

最終データの例:

任宗阳,邓二,19700118 06:41:23,19700118 06:41:23,186,浙江省,新疆维吾尔自治区

1.Beanクラスをカプセル化します

  • Beanクラスを作成する:パッケージデータ出力内容
  • toString()をオーバーライドする:出力フォーマットを定義する
  • WritableComparableから継承:シリアル化と逆シリアル化の方法を実現する
  • セッターメソッドとゲッターメソッドを定義する
  • カスタムset()メソッド:割り当てに使用
package 通信数据处理;

import org.apache.hadoop.io.WritableComparable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

public class BeanTest implements WritableComparable<BeanTest> {
    
    

    // 封装属性
    private String sender;  // 呼叫者
    private String receiver;  // 接受者
    private String start;    // 开始时间
    private String end;      // 结束时间
    private String interval; // 间隔
    private String p;      // 省份
    private String c;     // 城市

    // toString()
    @Override
    public String toString() {
    
    
        StringBuffer buffer = new StringBuffer();
        buffer.append(sender).append(",");
        buffer.append(receiver).append(",");
        buffer.append(start).append(",");
        buffer.append(end).append(",");
        buffer.append(interval).append(",");
        buffer.append(p).append(",");
        buffer.append(c);
        return buffer.toString();
    }

    // 无参构造
    public BeanTest() {
    
    
    }

    @Override
    public int compareTo(BeanTest o) {
    
    
        return 0;
    }

    @Override
    public void write(DataOutput dataOutput) throws IOException {
    
    
        dataOutput.writeUTF(sender);
        dataOutput.writeUTF(receiver);
        dataOutput.writeUTF(start);
        dataOutput.writeUTF(end);
        dataOutput.writeUTF(interval);
        dataOutput.writeUTF(p);
        dataOutput.writeUTF(c);
    }

    @Override
    public void readFields(DataInput dataInput) throws IOException {
    
    
        sender = dataInput.readUTF();
        receiver = dataInput.readUTF();
        start = dataInput.readUTF();
        end = dataInput.readUTF();
        interval = dataInput.readUTF();
        p = dataInput.readUTF();
        c = dataInput.readUTF();
    }

    public void set(String sender, String receiver, String start, String end, String interval, String p, String c) {
    
    
        this.sender = sender;
        this.receiver = receiver;
        this.start = start;
        this.end = end;
        this.interval = interval;
        this.p = p;
        this.c = c;
    }

    public String getSender() {
    
    
        return sender;
    }

    public void setSender(String sender) {
    
    
        this.sender = sender;
    }

    public String getReceiver() {
    
    
        return receiver;
    }

    public void setReceiver(String receiver) {
    
    
        this.receiver = receiver;
    }

    public String getStart() {
    
    
        return start;
    }

    public void setStart(String start) {
    
    
        this.start = start;
    }

    public String getEnd() {
    
    
        return end;
    }

    public void setEnd(String end) {
    
    
        this.end = end;
    }

    public String getInterval() {
    
    
        return interval;
    }

    public void setInterval(String interval) {
    
    
        this.interval = interval;
    }

    public String getP() {
    
    
        return p;
    }

    public void setP(String p) {
    
    
        this.p = p;
    }

    public String getC() {
    
    
        return c;
    }

    public void setC(String c) {
    
    
        this.c = c;
    }
}

トップに戻る


2.データ変換用のMapperTestクラス

  • ここでは、小さなキャッシュファイル操作の形態であった相対的に言っperson.txtて、city.txt彼らはキャッシュファイルとして使用される、ファイルの少ない内容。
  • まず、context.getCacheFiles()キャッシュファイルグループを取得します。人のデータセットの例を見てみましょう:元のデータセットが3つ、すなわち电话ID电话号码姓名に、私たちの目標はphone.txt、対応する番号の所有者名に最初の2列に、人物のデータの最初の列はそれほど重要な電話番号となり(未使用) 、したがって、処理中は無視されます。同じ都市データセットの最初の列も無視できます〜
  • キャッシュ归属人归属地情報の形で扱われました。これは电话->人名地址ID->省份2つのキーと値のペアの形で、キーの値に対応するHashMap元のデータに情報を戻すことでget()、交換作業。
  • 時間データの変換には、SimpleDateFormatクラスを使用します(出力スタイルを指定します)。これは元々Stringデータのタイプであったため、最初Longに時間タイプデータのタイプに変換する必要があります(Long.parseLong(String型原始数据))。時間間隔は、単に終了時間から開始時間を引いたものです。
package 通信数据处理;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.*;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.HashMap;

public class MapperTest extends Mapper<LongWritable, Text, BeanTest, NullWritable> {
    
    

    String sender;    // 拨号人
    String receiver;  // 接收人
    String p;         // 拨号人居住地
    String c;         // 接受者居住地
    String start;     // 拨号时间
    String end;       // 挂机时间
    String interval;  // 间隔时间
    HashMap<String, String> people = new HashMap();  // 存储人员数据缓存的内容
    HashMap<String, String> provience = new HashMap();  // 存储省份数据缓存的内容
    BeanTest k = new BeanTest();

    @Override
    protected void setup(Context context) throws IOException, InterruptedException {
    
    
        //分别获取缓存文件中的数据
        //  1.获取所有缓存文件集
        URI[] cacheFiles = context.getCacheFiles();
        String line;
        //  2.获取人员文件中的数据
        String path1 = cacheFiles[0].getPath().toString();
        BufferedReader person = new BufferedReader(new InputStreamReader(new FileInputStream(path1),"UTF-8"));
        while (StringUtils.isNotEmpty(line = person.readLine())){
    
    
            // 7,18000696806,赵贺彪
            String[] fields = line.split(",");
            people.put(fields[1],fields[2]); // 存储18000696806-->赵贺彪
        }
        //  3.获取省份文件中的数据
        String path2 = cacheFiles[1].getPath().toString();
        BufferedReader city = new BufferedReader(new InputStreamReader(new FileInputStream(path2),"UTF-8"));
        while (StringUtils.isNotEmpty(line = city.readLine())){
    
    
            // 1,110000,北京市
            String[] fields = line.split(",");
            provience.put(fields[1],fields[2]); // 存储110000-->北京市
        }
        //  4.关闭资源
        IOUtils.closeStream(person);
        IOUtils.closeStream(city);

    }

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    
    

        // 18620192711,15733218050,1506628174,1506628265,650000,810000 获取一行数据
        String line = value.toString();
        // 拆分
        String[] fields = line.split(",");
        // 替换拨号及接收人名信息\以及他们的所在省份信息
        sender = people.get(fields[0]);
        receiver = people.get(fields[1]);
        p = provience.get(fields[4]);
        c = provience.get(fields[5]);
        // 转换时间日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        start = sdf.format(Long.parseLong(fields[2]));
        end = sdf.format(Long.parseLong(fields[3]));
        interval = Long.parseLong(fields[3]) - Long.parseLong(fields[2])+"秒";
        k.set(sender,receiver,start,end,interval,p,c);
        System.out.println(k);
        // 写出
        context.write(k,NullWritable.get());
    }
}

トップに戻る


3.レデューサークラスの出力データ

package 通信数据处理;

import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;

public class ReducerTest extends Reducer<BeanTest, NullWritable,BeanTest, NullWritable> {
    
    
    @Override
    protected void reduce(BeanTest key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
    
    
        // 直接写出
        for (NullWritable v:values){
    
    
            context.write(key,NullWritable.get());
        }
    }
}

トップに戻る


4.DriverTestクラス構成ジョブ

package 通信数据处理;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.net.URI;

public class DriverTest {
    
    
    public static void main(String[] args) {
    
    
        Job job;
        Configuration conf = new Configuration();
        try {
    
    
            // 获取job
            job = Job.getInstance(conf);

            // 基础配置
            job.setMapperClass(MapperTest.class);
            job.setReducerClass(ReducerTest.class);
            job.setJarByClass(DriverTest.class);
            job.setMapOutputKeyClass(BeanTest.class);
            job.setMapOutputValueClass(NullWritable.class);
            job.setOutputKeyClass(BeanTest.class);
            job.setOutputValueClass(NullWritable.class);

            // 配置缓存文件
            URI[] uris = new URI[2];
            uris[0] = new URI("file:///G:/Projects/IdeaProject-C/MapReduce/src/main/java/通信数据处理/cache/person.txt");
            uris[1] = new URI("file:///G:/Projects/IdeaProject-C/MapReduce/src/main/java/通信数据处理/cache/city.txt");
            job.setCacheFiles(uris);

            // 输入输出文件
            FileInputFormat.setInputPaths(job, new Path("G:\\Projects\\IdeaProject-C\\MapReduce\\src\\main\\java\\通信数据处理\\data\\phone.txt"));
            FileOutputFormat.setOutputPath(job, new Path("G:\\Projects\\IdeaProject-C\\MapReduce\\src\\main\\java\\通信数据处理\\output"));
            boolean b = job.waitForCompletion(true);
            System.exit(b ? 0 : 1);

        } catch (Exception e){
    
    
            e.printStackTrace();
        }
    }
}

ここに画像の説明を挿入します

トップに戻る


おすすめ

転載: blog.csdn.net/qq_45797116/article/details/114582563