【问题标题】:Java: Reorder elements of a multi-dimentional arrayJava:重新排序多维数组的元素
【发布时间】:2016-01-04 23:37:28
【问题描述】:

我正在寻找一种内存高效且快速的方法来置换 Java 中多维数组的维度。

我的意思是将数组double[rows][cols][slices] 转换为数组double[slices][rows][cols]。(类似于this Matlab function)我知道所有行元素具有相同数量的列并且所有列具有相同数量的切片.

我总是在单个切片上工作,这使得double[rows][cols][slices] 数组非常不方便。我考虑创建一个getSlice(double[][][] array, int slice) 函数,但我的数组有几个 GB 的大小,而且我经常访问切片。所以这似乎是多余的工作。

准确地说我的问题: 在速度和内存使用方面,有没有比创建新数组并逐个元素复制旧数组更好的方法来排列数组维度?或者是否有一种完全不同且更优雅的方式来解决我迄今为止错过的问题?

回答 我现在按照建议封装了数据。为此,我还使用了来自ImageJ 的 ImagePlus、ImageStack 和 ImageProcessor 类,因为它们已经提供了我需要的大部分功能。从内存效率的角度来看,它们似乎还可以。

【问题讨论】:

  • 内存效率快?如果你只能拥有一个,你更喜欢哪一个?
  • 这可能是一个愚蠢的问题,但是为什么您实际上需要将单个切片作为double[][] 实例?这些切片是否作为参数传递给接受 double[][] 的方法?
  • 几年前,我使用了 cern.colt.matrix 库,其中包含许多有用的矩阵运算(不确定效率,但可能比从头开始构建更好)。
  • “有没有比创建一个新数组并逐个元素复制旧数组更好的方法来置换数组维度?”不,不是在 Java 中。在其他语言中,您可以假设数组元素是连续的,并且可以通过一个内存进程获取一个维度,尽管内存移动仍然一次完成一个地址。
  • @AndyTurner:因为我只需要做一次,所以我会选择内存高效

标签: java arrays multidimensional-array


【解决方案1】:

由于您没有提供有关如何使用数据的任何信息,这可能不相关,但我建议将数据封装在一个类中,以便永远不会直接访问数据。

您可以针对您的情况进行具体说明,或者更通用。我会显示通用的。

public interface Array3D {
    public double get(int x, int y, int z);
    /**
      * Returns a 2D view of the 3D plane for the given X, mapping (y,z) to (x,y).
      */
    public Array2D forX(int x);
    /**
      * Returns a 2D view of the 3D plane for the given Y, mapping (x,z) to (x,y).
      */
    public Array2D forY(int y);
    /**
      * Returns a 2D view of the 3D plane for the given Z.
      */
    public Array2D forZ(int z);
}
public interface Array2D {
    public double get(int x, int y);
    /**
      * Returns a 1D Y-axis view of the 2D plane for the given X.
      */
    public Array1D forX(int x);
    /**
      * Returns a 1D X-axis view of the 2D plane for the given Y.
      */
    public Array1D forY(int y);
    /**
      * Copies the data. Use sparingly.
      */
    public double[][] toArray();
}
public interface Array1D {
    public double get(int index);
    /**
      * Copies the data. Use sparingly.
      */
    public double[] toArray();
}

Array3D 的实现类将携带实际数据。 Array2DArray1D 的实现类不会携带任何数据,因为它们是 3D 数据的“视图”。

【讨论】:

  • 将数据封装到一个类中可能总是在 Java 中更好的方法。然而,在这种情况下,我担心这个接口函数的多次调用会产生太多开销,
猜你喜欢
  • 1970-01-01
  • 2012-08-11
  • 2016-05-29
  • 2020-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-06
相关资源
最近更新 更多