java - 在文本文件中转置矩阵的有效方法是什么?

标签 java matrix transpose

我有一个包含二维矩阵的文本文件。它看起来像下面这样。

01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
16 17 18 19 20

如您所见,每行由换行符分隔,每列由空格分隔。我需要以有效的方式转置这个矩阵。

01 06 11 16
02 07 12 17
03 08 04 05
04 09 14 19
05 10 15 20

实际上,矩阵是 10,000 x 14,000。各个元素是 double /浮点型。尝试将这个文件/矩阵全部转置在内存中,即使不是不可能,也是昂贵的。

有谁知道 util API 可以做这样的事情或有效的方法吗?

我尝试过的:我天真的方法是为(转置矩阵的)每一列创建一个临时文件。因此,如果有 10,000 行,我将有 10,000 个临时文件。当我读取每一行时,我会标记每个值,并将该值附加到相应的文件中。因此,通过上面的示例,我将得到如下所示的内容。

file-0: 01 06 11 16
file-1: 02 07 12 17
file-3: 03 08 13 18
file-4: 04 09 14 19
file-5: 05 10 15 20

然后我读回每个文件并将它们附加到一个文件中。我想知道是否有更聪明的方法,因为我知道文件 I/O 操作将是一个痛点。

最佳答案

具有最小内存消耗和极低性能的解决方案:

import org.apache.commons.io.FileUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class MatrixTransposer {

  private static final String TMP_DIR = System.getProperty("java.io.tmpdir") + "/";
  private static final String EXTENSION = ".matrix.tmp.result";
  private final String original;
  private final String dst;

  public MatrixTransposer(String original, String dst) {
    this.original = original;
    this.dst = dst;
  }

  public void transpose() throws IOException {

    deleteTempFiles();

    int max = 0;

    FileReader fileReader = null;
    BufferedReader reader = null;
    try {
      fileReader = new FileReader(original);
      reader = new BufferedReader(fileReader);
      String row;
      while((row = reader.readLine()) != null) {

        max = appendRow(max, row, 0);
      }
    } finally {
      if (null != reader) reader.close();
      if (null != fileReader) fileReader.close();
    }


    mergeResultingRows(max);
  }

  private void deleteTempFiles() {
    for (String tmp : new File(TMP_DIR).list()) {
      if (tmp.endsWith(EXTENSION)) {
        FileUtils.deleteQuietly(new File(TMP_DIR + "/" + tmp));
      }
    }
  }

  private void mergeResultingRows(int max) throws IOException {

    FileUtils.deleteQuietly(new File(dst));

    FileWriter writer = null;
    BufferedWriter out = null;

    try {
      writer = new FileWriter(new File(dst), true);
      out = new BufferedWriter(writer);
      for (int i = 0; i <= max; i++) {
        out.write(FileUtils.readFileToString(new File(TMP_DIR + i + EXTENSION)) + "\r\n");
      }
    } finally {
      if (null != out) out.close();
      if (null != writer) writer.close();
    }
  }

  private int appendRow(int max, String row, int i) throws IOException {

    for (String element : row.split(" ")) {

      FileWriter writer = null;
      BufferedWriter out = null;
      try {
        writer = new FileWriter(TMP_DIR + i + EXTENSION, true);
        out = new BufferedWriter(writer);
        out.write(columnPrefix(i) + element);
      } finally {
        if (null != out) out.close();
        if (null != writer) writer.close();
      }
      max = Math.max(i++, max);
    }
    return max;
  }

  private String columnPrefix(int i) {

    return (0 == i ? "" : " ");
  }

  public static void main(String[] args) throws IOException {

    new MatrixTransposer("c:/temp/mt/original.txt", "c:/temp/mt/transposed.txt").transpose();
  }
}

关于java - 在文本文件中转置矩阵的有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9782939/

相关文章:

hadoop - pyspark数据帧转置问题

java - 超时后自动关闭对话框并取消响应

python - 在 python 中准备一个返回矩阵有什么好处?

python - 减少行梯队表单脚本在特定情况下不起作用

python - 转置后找不到列名

C、使用动态内存分配的矩阵转置乘法

java - 为什么 gradle 不会覆盖不同 Android 风格的 Java 类?

java - 是否有可能以某种方式继承修改字节码的最终类?

java - JPA:将实体与现有 ID 合并

r - 如何在两个数据框列表上应用函数?