![](/img/trans.png)
[英]Using the AWS S3 Java SDK, what is the fastest way to determine if the authorization (access key and secret key) is correct?
[英]What's the fastest way to access a dataset with Java?
我有一个大文件,其中包含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());
}
更新:根据我在答案中收到的反馈,我重新编写了代码,现在代码运行时间为3秒而不是6分钟(对于10,000行),这意味着整个文件只需10分钟...但是关于如何操作的任何其他建议加快速度将不胜感激:
//load data file File f = new File("data/primary_training_short.csv");
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
}
data[x][y] = oneDdata.remove(0);
那将是非常低效的。 每次从ArrayList中删除第一个条目时,所有其他条目都需要向下移动。
您至少要创建一个自定义TableModel,这样就不必两次复制数据。
如果要将数据保留在数据库中,请在网上搜索ResultSet TableModel。
如果要将其保持为CSV格式,则可以将ArrayList用作TableModel的数据存储。 因此,您的扫描程序代码会将数据直接读取到ArrayList中。 请参阅“ 列表表模型”以获取一种此类解决方案。 或者您可能想使用Bean Table Model 。
当然,真正的问题是谁将有时间浏览所有180万条记录? 因此,您实际上应该使用数据库并具有查询逻辑来过滤从数据库返回的行。
我的程序只需要访问数据的每一行一次,因此不需要将整个数据集保存在RAM中
那么,为什么要在JTable中显示它呢? 这意味着整个数据将存储在内存中。
Sqllite是一个基于数据库的轻量级文件,据我说,这是解决您问题的最佳解决方案。
看看这个非常好的java驱动程序。 我将其用于我的一个NLP项目,并且效果很好。
这就是我的理解:您的要求是对加载的数据执行某种算法,而在运行时也是如此
由于两组数据之间没有关联,并且您在数据上执行的算法/计算是自定义逻辑(在SQL中没有内置函数),这意味着即使不使用Java也可以在Java中做到这一点任何数据库,这应该是最快的。
但是,如果您在两组数据上执行的逻辑/计算在SQL中具有等效功能,并且有一个单独的数据库运行良好的硬件(即更多的内存/ CPU),则可以通过Procedure / SQL中的功能可能会更好。
您可以使用opencsv包,它们的CSVReader可以遍历大型CSV文件,您还应该使用在线学习方法(如NaiveBayes,LinearRegression)处理此类大型数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.