【问题标题】:Loading multi-dimensional array dynamically动态加载多维数组
【发布时间】:2018-03-13 02:24:36
【问题描述】:

我有以下代码。它在概念上大致类似于 python reshape 函数。它成功地将一维数据加载到多维数组中,直到运行时才知道其维度。例如{209,64,64,3}。我必须遍历一维数据并为数组的每个维度创建正确的索引。

private void InitializeData()
{
  var imageData = ImageData.Load(txtFileName.Text); // one dimensional array
  var dimensions = txtDimensions.Text.Split(',').Select(d => int.Parse(d)).ToArray(); // e.g., {-1,64,64,3}
  int elements = 1;
  foreach (var dim in dimensions.Skip(1))
  {
    elements *= dim;
  }
  dimensions[0] = imageData.Length / elements; // {209,64,64,3}
  // create multipliers
  var multipliers = new int[dimensions.Length - 1];
  for (var dimension = 1; dimension < dimensions.Length; dimension++)
  {
    var multiplier = 1;
    for (var followingdimension = dimension; followingdimension < dimensions.Length; followingdimension++)
    {
      multiplier *= dimensions[followingdimension];
    }
    multipliers[dimension - 1] = multiplier;
  }
  // load data
  var dataArray = Array.CreateInstance(typeof(int), dimensions);
  var indexes = new int[dimensions.Length];
  for (var imageDataIndex = 0; imageDataIndex < imageData.Length; imageDataIndex++)
  {
    indexes[0] = imageDataIndex / multipliers[0];
    indexes[dimensions.Length - 1] = imageDataIndex % multipliers[multipliers.Length - 1];
    for (var multiplier = 1; multiplier < dimensions.Length - 1; multiplier++)
      indexes[multiplier] = (imageDataIndex / multipliers[multiplier]) % dimensions[multiplier];
    dataArray.SetValue(imageData[imageDataIndex], indexes);
  }
}

有没有更快或更优雅的方式来做到这一点?我确实意识到这是两件不同的事情。我将对优雅的建议进行基准测试,但我仍然希望看到它们。因为这实在是太难看了,写起来太痛苦了,不是最好的方法。

请注意(请)

数据可能并不总是图像数据,所以我不是在寻找位图操作。这只是发生在这里,但不一定是典型案例。而且,我的目标不是得到一个位图,而是一个数组。

【问题讨论】:

  • dataArray 创建后的使用情况如何?你用什么代码来访问它的元素?
  • @MatthewWatson,嗨。它将参与矩阵运算。这将是一个单独的查询,如何在 c# 中向量化数组操作。我还没有写那个代码。在数学中,如果你有两个矩阵,你可以做 A * B 或 A - 4 等。我假设在 c# 中,矩阵是一个 n 维常规数组。

标签: c# arrays


【解决方案1】:

感谢How to reshape an Array in c#,我得到了部分答案

代码可以替换为:

  var imageData = ImageData.Load(txtFileName.Text); // one dimensional array
  // e.g., {209,64,64,3}
  var dimensions = txtDimensions.Text.Split(',').Select(d => int.Parse(d)).ToArray();
  int elements = 1;
  foreach (var dim in dimensions.Skip(1))
  {
    elements *= dim;
  }
  dimensions[0] = imageData.Length / elements;
  // load data
  var dataArray = Array.CreateInstance(typeof(int), dimensions);
  Buffer.BlockCopy(imageData, 0, dataArray, 0, imageData.Length * sizeof(int));

如果有比Buffer.BlockCopy 或更简单的方法来执行实际加载,我会感到惊讶。事实证明,无论您的原始数据采用何种维度形式,BlockCopy 都会处理它,只要您可以将目标维度指定为目标数组的一部分。

我将继续寻找进一步完善原始代码其余部分的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-16
    • 2016-01-28
    • 2014-11-09
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    相关资源
    最近更新 更多