MapReduce Join拼接数据

这篇博客介绍了如何使用MapReduce在Hadoop环境中进行数据拼接。通过创建JoinBean来处理数据,确保读写顺序一致。在map阶段,根据用户ID聚合数据,而在reduce阶段完成实际的拼接操作。在reduce的setup方法中获取文件名,提高效率。最终,通过调整JavaBean的toString方法,可以优化结果展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读取两个数据,一个数据存放用户的id,性别和年龄,一个数据存放的电影的uid,id等信息但缺少用户信息,将二者拼接起来

本次采用的是在reduce阶段拼接,也可以在map阶段拼接

1.JoinBean

今天碰到一个很尴尬的问题,read和write中的读写数据顺序必须一直,否则数据会混乱。检查了很久才发现,需要注意

package nuc.edu.ls.extend;

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

import org.apache.hadoop.io.Writable;

public class JoinBean implements Writable{
    private String uid;
    private String age;
    private String gender;
    private String movieId;
    private String rating;
    private String table;
	public String getUid() {
		return uid;
	}
	public void setUid(String uid) {
		this.uid = uid;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public String getMovieId() {
		return movieId;
	}
	public void setMovieId(String movieId) {
		this.movieId = movieId;
	}
	public String getRating() {
		return rating;
	}
	public void setRating(String rating) {
		this.rating = rating;
	}
	public String getTable() {
		return table;
	}
	public void setTable(String table) {
		this.table = table;
	}
	@Override
	public String toString() {
		return "JoinBean [uid=" + uid + ", age=" + age + ", gender=" + gender + ", movieId=" + movieId + ", rating="
				+ rating + ", table=" + table + "]";
	}
	@Override
	public void readFields(DataInput arg0) throws IOException {
		uid=arg0.readUTF();
		age=arg0.readUTF();
		gender=arg0.readUTF();
		movieId=arg0.readUTF();
		rating=arg0.readUTF();
		table=arg0.readUTF();
		
	}
	@Override
	public void write(DataOutput arg0) throws IOException {
		// TODO Auto-generated method stub
		arg0.writeUTF(uid);
		arg0.writeUTF(age);
		arg0.writeUTF(gender);
		arg0.writeUTF(movieId);
		arg0.writeUTF(rating);
		arg0.writeUTF(table);
		
	}
	public void set(String uid, String age, String gender, String movieId, String rating, String table) {
		this.uid = uid;
		this.age = age;
		this.gender = gender;
		this.movieId = movieId;
		this.rating = rating;
		this.table = table;
	}
	
    
}

 

2.任务

map将相同用d户id的数据汇集到一起,两数据的唯一联系就是uid

setup方法中获得了写入的文件名信息,写入setup中的好处在于只需要获取一次即可,提高效率

reduce阶段  随便取到一个用户信息(根据table即写入的文件名),就可以对集合中所有电影信息进行拼接了

package nuc.edu.ls.extend;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;


public class JoinMR {
	public static class MapTask extends Mapper<LongWritable, Text, Text, JoinBean> {
		String table;

		@Override
		protected void setup(Mapper<LongWritable, Text, Text, JoinBean>.Context context)
				throws IOException, InterruptedException {
			// TODO Auto-generated method stub
			FileSplit fileSplit = (FileSplit) context.getInputSplit();
			table = fileSplit.getPath().getName();
		}

		@Override
		protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, JoinBean>.Context context)
				throws IOException, InterruptedException {
			// TODO Auto-generated method stub
			String[] split = value.toString().split("::");
			JoinBean jb = new JoinBean();
			if (table.startsWith("users")) {
				jb.set(split[0], split[2], split[1], "null", "null", "user");
			} else {
				jb.set(split[0], "null", "null", split[1], split[2], "rating");
			}
//			System.out.print(jb.getUid()+"\\");
//			System.out.println(jb);
			context.write(new Text(jb.getUid()), jb);
		}
	}

	public static class ReduceTask extends Reducer<Text, JoinBean, JoinBean, NullWritable> {
		@Override
		protected void reduce(Text key, Iterable<JoinBean> values,
				Reducer<Text, JoinBean, JoinBean, NullWritable>.Context context)
				throws IOException, InterruptedException {
			// TODO Auto-generated method stub
			JoinBean user = new JoinBean();
			ArrayList<JoinBean> list = new ArrayList<>();
			for (JoinBean joinBean2 : values) {
				String table = joinBean2.getTable();
				if ("user".equals(table)) {
					user.set(joinBean2.getUid(), joinBean2.getAge(), joinBean2.getGender(), joinBean2.getMovieId(), joinBean2.getRating(), joinBean2.getTable());

				} else {
					JoinBean joinBean3 = new JoinBean();
					joinBean3.set(joinBean2.getUid(), joinBean2.getAge(), joinBean2.getGender(), joinBean2.getMovieId(), joinBean2.getRating(), joinBean2.getTable());
					list.add(joinBean3);
				}
			}
			System.out.print(key.toString()+"\\\\\\");
			System.out.println(user+"\\\\\\");
			// 拼接数据
			for (JoinBean join : list) {
				join.setAge(user.getAge());
				join.setGender(user.getGender());
				context.write(join, NullWritable.get());
			}

		}
	}
	public static void main(String[] args) throws Exception {
		System.setProperty("HADOOP_USER_NAME", "root");

		Configuration conf = new Configuration();
		Job job = Job.getInstance(conf, "eclipseToCluster");

		job.setMapperClass(MapTask.class);
		job.setReducerClass(ReduceTask.class);
		job.setJarByClass(JoinMR.class);
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(JoinBean.class);
		job.setOutputKeyClass(JoinBean.class);
		job.setOutputValueClass(NullWritable.class);
       // job.setCombinerClass(ReduceTask.class);
		FileInputFormat.addInputPath(job, new Path("d:/indata/"));
		FileOutputFormat.setOutputPath(job, new Path("d:/outdata/movie"));
		File file = new File("d:/outdata/movie");
        if(file.exists()) {
        	FileUtils.deleteDirectory(file);
        }
		boolean completion = job.waitForCompletion(true);
		System.out.println(completion ? 0 : 1);

	}

}

3.结果:

想结果好看可以修改JavaBean里面的toString方法

 

<think>好的,用户想了解数据处理与分析相关的复试常见问题及解答。首先我需要整理这方面的常见问题,确保覆盖基础概念、实际应用和编程技巧。 根据引用中的资料,引用[3]提到了数据结构的问题,比如用队列实现栈,还有树和二叉树的概念,这可能涉及到数据结构的基础知识。引用[2]讨论了判断重复数据的优化方法,这可能和数据处理中的去重操作有关。引用[4]提到了Python中的字符串处理问题,说明编程细节和内存管理也是考察点。 用户需要的是复试常见问题,所以应该包括理论知识和实际应用。首先,常见的数据结构问题,比如数组、链表、树等,然后是数据处理方法,如排序、查找、去重。接着是算法复杂度分析,比如时间空间复杂度。另外,数据库相关的SQL操作和优化也可能被问到。大数据处理框架如Hadoop或Spark的基础知识也可能涉及。 在编程方面,Python是常用的,所以需要涵盖Python的数据结构、库如Pandas、NumPy,以及内存管理和异常处理。例如,引用[4]中的字符串问题,可以引申到如何处理大数据时的内存优化。 还要考虑实际应用场景,比如数据清洗、特征工程、机器学习预处理步骤等。这些问题需要结合具体例子,说明解决方法和注意事项。 最后,根据用户提供的引用,需要自然地加入引用标识。例如,在讨论去重方法时引用[2],在Python内存问题时引用[4],数据结构问题引用[3]。 总结结构:分几个大类,每个类别下列出问题及答案,确保每个回答简洁明了,并正确引用相关来源。同时,生成的相关问题要覆盖用户可能关心的其他方面,如性能优化、实际应用、工具使用等。</think>### 数据处理与分析复试常见问题及解答 #### 一、数据结构与算法基础 1. **如何判断数据集中是否存在重复元素?** - **解答**: 若数据量较大,建议使用哈希表(HashSet)存储已遍历元素,通过一次扫描实现$O(n)$时间复杂度。例如在Python中: ```python def has_duplicate(arr): seen = set() for num in arr: if num in seen: return True seen.add(num) return False ``` 此方法避免了双重循环的低效性[^2]。 2. **如何用队列实现栈的功能?** - **解答**: 使用两个队列,每次插入新元素时,将其放入非空队列,出栈时则将元素逐个转移到另一个队列,直到最后一个元素弹出。时间复杂度为$O(n)$,空间复杂度$O(n)$[^3]。 --- #### 二、数据处理方法与复杂度 3. **快速排序的性能如何分析?** - **解答**: 平均时间复杂度为$O(n \log n)$,最坏情况(如数组已有序)退化为$O(n^2)$。优化方法包括随机选择基准元素或使用三数取中法[^1]。 4. **数据去重的优化方法有哪些?** - **解答**: - 内存充足时:哈希表去重(时间复杂度$O(n)$); - 数据量极大时:分治法(将数据分块处理)或布隆过滤器(空间效率高,但有一定误判率)[^2]。 --- #### 三、编程语言与工具实践 5. **Python中字符串拼接为何可能导致内存浪费?** - **解答**: 字符串为不可变对象,每次拼接会生成新对象。例如`str += "new"`在循环中会频繁创建新字符串,应改用`列表+join`方式优化内存[^4]。 6. **Pandas中如何处理缺失值?** - **解答**: - 删除缺失行:`df.dropna()`; - 填充缺失值:`df.fillna(value)`或均值/中位数填充; - 插值法:`df.interpolate()`。 --- #### 四、数据库与大数据 7. **SQL查询优化的常见手段?** - **解答**: - 添加索引(尤其是WHERE和JOIN涉及的字段); - 避免使用`SELECT *`,明确指定字段; - 分页查询时使用`LIMIT OFFSET`。 8. **简述MapReduce的工作原理** - **解答**: 分为`Map`阶段(将数据拆分为键值对)和`Reduce`阶段(合并相同键的值)。例如统计词频时,Map生成`(word,1)`,Reduce累加计数。 --- #### 五、实际应用场景 9. **数据清洗的关键步骤有哪些?** - **解答**: - 处理缺失值、异常值; - 统一数据格式(如日期标准化); - 去除重复数据; - 数据归一化或标准化。 10. **特征工程中如何选择有效特征?** - **解答**: - 统计方法:方差过滤、相关系数分析; - 模型辅助:基于树模型(如随机森林)的特征重要性排序; - 降维技术:PCA、LDA。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值