【发布时间】:2020-01-31 08:25:07
【问题描述】:
我有一个包含近 200 万行和 3 列(项目、评级、用户)的 CSV 文件。我能够将数据传输到二维字符串数组或列表中。但是,当我尝试解析数组以从中创建 CSV 文件时出现了我的问题,因为应用程序停止并且我不知道我需要等待多长时间才能等待程序完成运行。
基本上,我的最终目标是能够解析大型 CSV 文件,创建一个矩阵,其中每个不同的项目代表一行,每个不同的用户代表一列,评分位于用户和项目的交叉点。使用这个矩阵,然后我创建一个余弦相似度矩阵,其中行和列由项目表示,它们的余弦相似度位于两个不同项目的交点。
我已经知道如何创建 CSV 文件,但是在创建其他数组以进行比较时,我的问题属于大型循环结构。
有没有更好的方法来处理和计算大量数据,以免我的应用程序冻结?
我当前的程序执行以下操作:
- 获取大型 CSV 文件
- 通过大型 CSV 文件进行解析
- 创建类似于原始 CSV 文件的二维数组
- 创建不同项目的列表(每个不同的项目由索引号表示)
- 创建不同用户列表(每个不同用户由索引号表示)
- 创建 2D 数组,其中行索引表示项目,列索引表示用户,结果数组 [row][column] = rating
- 计算两个矩阵的余弦相似度
- 创建二维数组,其中行索引和列索引表示项,从而导致数组 [行] [列] = 余弦相似度
我注意到我的程序在执行第 4 步和第 5 步时冻结 如果我删除第 4 步和第 5 步,它仍会在第 6 步冻结
我已经附上了我的那部分代码
FileInputStream stream = null;
Scanner scanner = null;
try{
stream = new FileInputStream(fileName);
scanner = new Scanner(stream, "UTF-8");
while (scanner.hasNextLine()){
String line = scanner.nextLine();
if (!line.equals("")){
String[] elems = line.split(",");
if (itemList.isEmpty()){
itemList.add(elems[0]);
}
else{
if (!itemList.contains(elems[0]))
itemList.add(elems[0]);
}
if (nameList.isEmpty()){
nameList.add(elems[2]);
}
else{
if (!nameList.contains(elems[2]))
nameList.add(elems[2]);
}
for (int i = 0; i < elems.length; i++){
if (i == 1){
if (elems[1].equals("")){
list.add("0");
}
else{
list.add(elems[1]);
}
}
else{
list.add(elems[i]);
}
}
}
}
if (scanner.ioException() != null){
throw scanner.ioException();
}
}
catch (IOException e){
System.out.println(e);
}
finally{
try{
if (stream != null){
stream.close();
}
}
catch (IOException e){
System.out.println(e);
}
if (scanner != null){
scanner.close();
}
}
【问题讨论】:
-
恕我直言,您在这里遇到了内存问题。垃圾收集器尝试释放内存以继续,但没有得到。所以使用 -Xmx java 参数增加你的堆空间。降低数据结构的内存占用。另一种可能性是将您的 CSV 放入数据库(H2、Derby 或大型数据库)并在那里进行数据查询。
标签: java arrays list csv memory-management