java - 将文本文件中的大矩阵加载到 Java 数组中

标签 java arrays text-files java.util.scanner scientific-computing

我的数据存储在文本文件中的大型矩阵中,其中包含数百万行和 4 列逗号分隔值。 (每列存储一个不同的变量,每行存储所有四个变量的不同毫秒数据。)在前十几行中还有一些不相关的标题数据。我需要编写 Java 代码来将这些数据加载到四个数组中,一个数组对应文本矩阵中的每一列。

Java 代码还需要能够判断 header 何时完成,以便可以将第一个数据行拆分为 4 个数组的条目。最后,Java 代码需要遍历数百万行数据,重复将每一行分解为四个数字的过程,每个数字都输入到数字所在列的适当数组中。

我怎样才能改变下面的代码来完成这个?我想找到完成这种数百万行处理的最快方法。

这是我的代码:

主类2.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();  
}
}

读取文件2.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 的模式匹配代码无法放置数字的位置保留零。 (这是我最初编写代码的结果。)

我很难找到保留零的索引,但除了 header 所在的预期零之外,似乎还有更多的零。当我绘制 temp[1] 输出的导数时,我看到许多尖锐的尖峰,其中 temp[1] 可能是假零。如果我能分辨出 temp[1]、temp[2] 和 temp[3] 中的零在哪里,我也许能够修改模式匹配以更好地保留所有数据。

另外,最好将输出数组缩短为不再包含标题在输入文件中所在的行。但是,我发现的有关可变长度数组的教程仅显示了过于简单的示例,例如:

int[] anArray = {100, 200, 300, 400};

如果代码不再使用 scan1 来生成 scan1Count,它可能会运行得更快。我不想通过使用低效方法生成可变长度数组来减慢代码速度。在模式匹配无法将输入行拆分为 4 个数字的情况下,我也不想跳过时间序列中的数据。我宁愿保留时间序列中的零,以便我可以找到它们并使用它们来 Debug模式匹配。

这些事情可以用快速运行的代码来完成吗?


第二次编辑

所以

"-{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 个逗号,则可以使用正则表达式 (http://www.vogella.de/articles/JavaRegularExpressions/article.html) 控制每一行。 如果该行恰好显示 4 个逗号,您可以使用 String.split 拆分该行并填充 4 数组,否则您将在下一行传递。

        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];


            //Read File Line By Line
            try {
                File tempfile = new File("samedatafile.txt");
                FileInputStream fis = new FileInputStream(tempfile);
                DataInputStream in = new DataInputStream(fis);
                BufferedReader br = new BufferedReader(new InputStreamReader(in));      
                String strLine;
                int i = 0;
                while ((strLine = br.readLine()) != null)   {
                      Pattern pattern = Pattern.compile("-{0,1}\\d+.\\d+,-{0,1}\\d+.\\d+,-{0,1}\\d+.\\d+,-{0,1}\\d+.\\d+,");
                      Matcher matcher = pattern.matcher(strLine);
                      if (matcher.matches()){
                          String[] split = strLine.split(",");              
                          outputArray1[i] = Double.parseDouble(split[0]);
                          outputArray2[i] = Double.parseDouble(split[1]);
                          outputArray3[i] = Double.parseDouble(split[2]);
                          outputArray4[i] = Double.parseDouble(split[3]);
                      }
                      i++;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            double[][] temp = new double[4][];
            temp[0]= outputArray1;
            temp[1]= outputArray2;
            temp[2]= outputArray3;
            temp[3]= outputArray4;
            return temp;
        }

关于java - 将文本文件中的大矩阵加载到 Java 数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6421757/

相关文章:

java - android 通知 - RemoteServiceException

java - 如何将嵌套 JSON 映射到简单对象?

c - 如何检查矩阵中是否存在元素?

c - 文件指针在 while 循环的第二次迭代中变为 NULL

python - 如何将文本文件作为字符串读取?

java - 数组:删除输出 int

java - JTextField 在 Eclipse 中一切看起来都正常,但无法编译

c - 在 float 变量中排序后数组值发生变化

python - 如何在 Python 中用另一个数组替换数组的每个元素?

c - 如何打印文本文件中每行的第二个单词?