使用Java访问数据集的最快方法是什么?

Tec*_*ony 1 java machine-learning

我有一个大文件,有180万行数据,我需要能够读取我正在编写的机器学习程序.数据当前是CSV文件,但显然我可以根据需要将其放在数据库或其他结构中 - 它不需要定期更新.

我目前使用的代码如下.我首先将数据导入数组列表,然后将其传递给表模型.这是非常慢的,目前只花了六分钟执行前10,000行,这是不可接受的,因为我需要能够经常测试不同的数据对数据.

我的程序只需要访问数据的每一行,因此不需要将整个数据集保存在RAM中.我最好是从数据库中读取数据,还是有更好的方法逐行读取CSV文件但是更快?

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class CSVpaser {

public static TableModel parse(File f) throws FileNotFoundException {
    ArrayList<String> headers = new ArrayList<String>();
    ArrayList<String> oneDdata = new ArrayList<String>();
    //Get the headers of the table.
    Scanner lineScan = new Scanner(f);
    Scanner s = new Scanner(lineScan.nextLine());
    s.useDelimiter(",");
    while (s.hasNext()) {
        headers.add(s.next());
    }

    //Now go through each line of the table and add each cell to the array list
    while (lineScan.hasNextLine()) {
       s =  new Scanner(lineScan.nextLine());
       s.useDelimiter(", *");
       while (s.hasNext()) {
           oneDdata.add(s.next());
       }
    }
    String[][] data = new String[oneDdata.size()/headers.size()][headers.size()];
    int numberRows = oneDdata.size()/headers.size();

    // Move the data into a vanilla array so it can be put in a table.
    for (int x = 0; x < numberRows; x++) {
        for (int y = 0; y < headers.size(); y++) {
            data[x][y] = oneDdata.remove(0);
        }
    }

    // Create a table and return it
    return new DefaultTableModel(data, headers.toArray());


}
Run Code Online (Sandbox Code Playgroud)

更新:根据我在答案中收到的反馈,我已经重写了代码,它现在在3秒而不是6分钟(10,000行)运行,这意味着整个文件只需要10分钟...但是对于如何进一步的建议加快它将不胜感激:

       //load data file
    File f = new File("data/primary_training_short.csv");
Run Code Online (Sandbox Code Playgroud)
    Scanner lineScan = new Scanner(f);
    Scanner s = new Scanner(lineScan.nextLine());
    s.useDelimiter(",");

    //now go through each line of the results
    while (lineScan.hasNextLine()) {
       s =  new Scanner(lineScan.nextLine());
       s.useDelimiter(", *");
       String[] data = new String[NUM_COLUMNS];

       //get the data out of the CSV file so I can access it
       int x = 0;
       while (s.hasNext()) {
           data[x] = (s.next());
           x++;
       }
       //insert code here which is excecuted each line
   }
Run Code Online (Sandbox Code Playgroud)

cam*_*ckr 5

data[x][y] = oneDdata.remove(0);
Run Code Online (Sandbox Code Playgroud)

那将是非常低效的.每次从ArrayList中删除第一个条目时,所有其他条目都需要向下移动.

您至少需要创建一个自定义TableModel,因此您不必复制数据两次.

如果要将数据保留在数据库中,请在网上搜索ResultSet TableModel.

如果要将其保留为CSV格式,则可以使用ArrayList作为TableModel的数据存储.因此,您的扫描程序代码会将数据直接读入ArrayList.有关此类解决方案,请参阅列表模型.或者您可能想要使用Bean表模型.

当然真正的问题是谁将有时间浏览所有1.8M记录?所以你真的应该使用数据库并使用查询逻辑来过滤从数据库返回的行.

我的程序只需要访问数据的每一行,因此不需要将整个数据集保存在RAM中

那么为什么要在JTable中显示它呢?这意味着整个数据将在内存中.