您的位置:首页 > 其它

如何将多个文本数据转化为指定数据格式[以电影数据为例](数据预处理)

2016-11-16 09:50 260 查看
数据格式

目标数据格式

程序

局限性

本文为原创博客,仅供技术学习使用。未经允许,禁止将其复制下来上传到百度文库等平台。如有转载请注明本文博客的地址(链接)

数据格式

首先,我来介绍一下数据格式。存在多个文本,每个文本,里面包含电影的id,用户的id及用户对电影的评分,及评分时间。如下面两个表:

这张图为目录下的文本。一个文本表示,一部电影所有用户的评分及评分时间。





目标数据格式

如下图所示,为所需要转化成的目标数据格式。其中,一行表示:一个用户对所有电影的评分(矩阵),没有打分的电影为null值,即转化成了评分矩阵。



程序

这里主要包含两个类,分别是:

FileGetData类主要是用来文件的读写。

Test是main方法,进行数据的实际操作。



package main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
/**文件操作类
* @author 合肥工业大学管理学院  钱洋
* @blog http://blog.csdn.net/qy20115549/ * @mail 1563178220@qq.com
*/
public class FileGetData {
//将一个文本中数据的每一行存入list中
public List<String> getData (String fileName) throws IOException {
//读入的数据存入list<>中
List<String> Data=new ArrayList<String>();
File file = new File(fileName);
//FileReader顺序读取文件
FileReader fileReader = new FileReader(file);
//根据FileReader创建的实例
BufferedReader bufferedReader =new BufferedReader(fileReader);
String s=null;
while ((s=bufferedReader.readLine())!=null) {
Data.add(s);
}
bufferedReader.close();
fileReader.close();
return Data;
}
//获取目录下的文本目录
public List<String> getFiles( String filePath ){
List<String> filelist = new ArrayList<String>();
File root = new File( filePath );
File[] files = root.listFiles();
for ( File file : files )
{
if ( file.isDirectory() )
{
getFiles( file.getAbsolutePath() );
filelist.add( file.getAbsolutePath() );
}else{
filelist.add( file.getAbsolutePath() );
}
}
return filelist;
}
}


package main;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

/**文件操作类
* @author 合肥工业大学管理学院  钱洋
* @blog http://blog.csdn.net/qy20115549/ * @mail 1563178220@qq.com
*/
public class Test {

public static void main(String[] args) throws IOException {
FileGetData fileGetData=new FileGetData();
//获取目录下所有文件
List<String> fileList=fileGetData.getFiles("E:\\熊强师兄数据处理\\sample\\");
System.out.println(fileList.get(1));
Map<String, String> useridandmovieid=new HashMap<String, String>();
//获取所有用户id
TreeSet<Integer> uniqueuser_id = new TreeSet<Integer>();
//获取所用movieid
TreeSet<Integer> uniquemovie_id = new TreeSet<Integer>();
//循环每个目录下面的文件
for (int i = 0; i < fileList.size(); i++) {
List<String> data=fileGetData.getData(fileList.get(i));
for (int j = 1; j< data.size(); j++) {
//获取用户id
String userid=data.get(j).split(",")[0];
//获取电影id
String movieid=data.get(0).replaceAll(":", "");
String key=userid+":"+movieid;
//表示电影评分
String value=data.get(j).split(",")[1];
//useridandmovieid数据格式:用户id:电影id
useridandmovieid.put(key,value);
uniqueuser_id.add(Integer.parseInt(userid));
uniquemovie_id.add(Integer.parseInt(movieid));
}
}
//目标数据写入文本
BufferedWriter output = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( new File("E:\\熊强师兄数据处理\\combineAlluser.txt")),"utf-8"));
System.out.println(useridandmovieid.size());
//将同一个用户对所有电影的评分抽取出来,排成一行,并写入文本
Iterator<Integer> setIt = uniqueuser_id.iterator();
while ( setIt.hasNext() ){
int uniqueuser=setIt.next();
Iterator<Integer> setIt1 = uniquemovie_id.iterator();
//排成一行数据
String userrowscore=uniqueuser+"\t";
while ( setIt1.hasNext() ){
int uniquemovie=setIt1.next();
String uniqueuserkey=uniqueuser+":"+uniquemovie;
String score=useridandmovieid.get(uniqueuserkey);
userrowscore+=score+"\t";

}
output.append(userrowscore+"\n");
}
output.close();

}

}


局限性

从上面的Test程序中可以看出,这里使用的map作为数据中转站。这里就有一个问题,就是大数据怎么办?

针对数据量不是很大的情况,完全没问题。针对大一点的数据集,就会出现:Java heap space

针对这个问题的解决,我再写一篇博客,介绍怎么解决。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐