我的数据存储在大型矩阵中,这些矩阵存储在文本文件中,有数百万行和4列逗号分隔的值。(每一列存储一个不同的变量,每一行存储所有四个变量的不同毫秒的数据。)在前十几行中还有一些不相关的标题数据。我需要编写Java代码来将这些数据加载到四个数组中,文本矩阵中的每一列对应一个数组。
Java代码还需要能够判断头何时完成,以便第一个数据行可以被拆分为4个数组的条目。最后,Java代码需要遍历数百万个数据行,重复将每行分解为四个数字的过程,每个数字都输入到数字所在列的适当数组中。
我如何修改下面的代码来实现这一点?我想找到最快的方法来完成数百万行的处理。
下面是我的代码:
MainClass2.java
package packages;
public class MainClass2{
public static void main(String[] args){
readfile2 r = new readfile2();
r.openFile();
int x1Count = r.readFile();
r.populateArray(x1Count);
r.closeFile();
}
}
readfile2.java
package packages;
import java.io.*;
import java.util.*;
public class readfile2 {
private Scanner scan1;
private Scanner scan2;
public void openFile(){
try{
scan1 = new Scanner(new File("C:\\test\\samedatafile.txt"));
scan1 = new Scanner(new File("C:\\test\\samedatafile.txt"));
}
catch(Exception e){
System.out.println("could not find file");
}
}
public int readFile(){
int scan1Count = 0;
while(scan1.hasNext()){
scan1.next();
scan1Count += 1;
}
return scan1Count;
}
public double[] populateArray(int scan1Count){
double[] outputArray1 = new double[scan1Count];
double[] outputArray2 = new double[scan1Count];
double[] outputArray3 = new double[scan1Count];
double[] outputArray4 = new double[scan1Count];
int i = 0;
while(scan2.hasNext()){
//what code do I write here to:
// 1.) identify the start of my time series rows after the end of the header rows (e.g. row starts with a number AT LEAST 4 digits in length.)
// 2.) split each time series row's data into a separate new entry for each of the 4 output arrays
i++;
}
return outputArray1, outputArray2, outputArray3, outputArray4;
}
public void closeFile(){
scan1.close();
scan2.close();
}
}
以下是典型数据文件的前19行:
text and numbers on first line
1 msec/sample
3 channels
ECG
Volts
Z_Hamming_0_05_LPF
Ohms
dz/dt
Volts
min,CH2,CH4,CH41,
,3087747,3087747,3087747,
0,-0.0518799,17.0624,0,
1.66667E-05,-0.0509644,17.0624,-0.00288295,
3.33333E-05,-0.0497437,17.0624,-0.00983428,
5E-05,-0.0482178,17.0624,-0.0161573,
6.66667E-05,-0.0466919,17.0624,-0.0204402,
8.33333E-05,-0.0448608,17.0624,-0.0213986,
0.0001,-0.0427246,17.0624,-0.0207532,
0.000116667,-0.0405884,17.0624,-0.0229672,
编辑
我测试了Shilaghae的代码建议。似乎起作用了。然而,所有结果数组的长度都与x1Count相同,因此在Shilaghae的模式匹配代码无法放置数字的地方仍保留零。(这是我最初编写代码的结果。
我很难找到零仍然存在的索引,但似乎有很多零除了那些预期的头在哪里。当我绘制temp[1]输出的导数时,我看到了一些尖锐的尖峰,其中temp[1]中的假零可能是。如果我能知道temp[1]、temp[2]和temp[3]中的零在哪里,我就可以修改模式匹配,以更好地保留所有数据。
另外,最好是简单地缩短输出数组,使其不再包含输入文件中头所在的行。然而,我找到的关于可变长度数组的教程只显示了过于简化的示例,如:
int[] anArray = {100, 200, 300, 400};
如果代码不再使用scan 1来生成scan 1Count,则它可能会运行得更快。我不想使用低效的方法来生成可变长度数组,从而降低代码的速度。我也不想在模式匹配无法将输入行拆分为4个数字的情况下跳过时间序列中的数据。我宁愿保留时间序列中的零,这样我就可以找到它们并使用它们来调试模式匹配。
这些事情可以在快速运行的代码中完成吗?
二次编辑
所以呢
"-{0,1}\\d+.\\d+,"
在表达式中重复多次:
"-{0,1}\\d+.\\d+,-{0,1}\\d+.\\d+,-{0,1}\\d+.\\d+,-{0,1}\\d+.\\d+,"
是吗
"-{0,1}\\d+.\\d+,"
分解为以下三个语句:
"-{0,1}" means that a minus sign occurs zero or one times, while
"\\d+." means that the minus sign(or lack of minus sign) is followed by several digits of any value followed by a decimal point, so that finally
"\\d+," means that the decimal point is followed by several digits of any value?
如果是这样,那么我的数据中的数字如“1.66667E-05”或“-8.06131E-05”怎么办?我刚刚扫描了一个输入文件,(在3+百万个4列行中)它包含638个包含E的数字,其中5个在第一列,633个在最后一列。
4条答案
按热度按时间ehxuflar1#
您可以逐行读取文件,并且对于每一行都可以使用正则表达式(http://www.vogella.de/articles/JavaRegularExpressions/article.html)进行控制,前提是该行正好显示4个逗号。如果这一行正好有4个逗号,你可以用String.split来分割这一行,然后填充4个数组,否则你就在下一行传递。
2izufjch2#
可以使用String.split()拆分每一行。
要跳过标题,您可以阅读前N行并丢弃它们(如果您知道有多少行),或者您需要寻找特定的标记-在没有看到数据的情况下很难提供建议。
您可能还需要稍微改变一下方法,因为您目前似乎是根据总行数来调整数组的大小(假设您的Scanner返回行数?)而不是省略标题行的计数。
wkftcu5l3#
我会通过简单地尝试将every行解析为四个数字来处理标题的问题,并丢弃解析不起作用的任何行。如果在标题行之后可能有不可解析的行,那么您可以在第一次获得“好”行时设置一个标志,然后报告任何后续的“坏”行。
用
String.split(...)
分割行。这不是绝对最快的方法,但你的程序的CPU时间将花在其他地方。所以这可能不重要qhhrdooz4#
最后的代码非常简单,只涉及使用string.split()和“,”作为正则表达式。为此,我必须手动删除输入文件中的标题,以便数据只包含用4个逗号分隔的数字的行。
如果有人好奇,最后的工作代码是: