我有一个将近200万行的CSV文件,其中包含3列(项目,等级,用户)。我能够将数据传输到2D字符串数组或列表中。但是,当我尝试解析数组以从中创建CSV文件时,就会出现问题,因为应用程序停止了,而且我不知道我要等多长时间才能完成程序的运行。
[基本上,我的最终目标是能够解析大型CSV文件,创建一个矩阵,其中每个不同的项目代表一行,每个不同的用户代表一列,评分位于用户与项目的交集。使用此矩阵,然后创建一个余弦相似度矩阵,其中行和列由项表示,其余弦相似度位于两个不同项的交点处。
我已经知道如何创建CSV文件,但是出于比较目的,在创建其他数组时,我的问题属于大型循环结构。
是否有更好的方法来处理和计算大量数据,以使我的应用程序不冻结?
我当前的程序执行以下操作:1.提取大型CSV文件2.解析大型CSV文件3.创建类似于原始CSV文件的2D数组4.创建不同项目的列表(每个不同项目由索引号表示)5.创建独立用户列表(每个独立用户由索引号表示)6.创建2D数组,其中行索引代表项,列索引代表用户,从而导致array [row] [column] = rating7.计算两个矩阵的余弦相似度8.创建二维数组,行和列索引均表示导致array [row]的项[列] =余弦相似度
我注意到我的程序在到达步骤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();
}
}
String
。对于score
列(大概是数字),您应该能够将其解析为数字值并存储它而不是字符串表示形式。为什么?字符串比数字使用更多的内存。即使是[[empty字符串uses 40 bytes,单个数值也可以是as little as one byte。如果单个byte
可以工作(数字范围是-128到127),则可以将〜80MB的内存使用量替换为〜2MB。即使使用int
(4字节),也将比String
有很大的改进。如果数据中还存在其他任何数字(或布尔值)值,则可以进一步减少。