如何在 IDL 中将浮点数组保存在多维数组中?

How can I save float arrays in a multiple dimension array in IDL?

我试图在多维数组中保存许多浮点数组。每个浮点数组都属于维度数组中的特定索引。

浮点数组的数组大小为[128, 128].

我尝试了什么?

(我说得很简单,现在我没有使用 [128, 128] 尺寸。)

multiple_array = MAKE_ARRAY(5, 3, /FLOAT)
> multiple_array
  0.00000000      0.00000000      0.00000000      0.00000000      0.00000000
  0.00000000      0.00000000      0.00000000      0.00000000      0.00000000
  0.00000000      0.00000000      0.00000000      0.00000000      0.00000000

float_array = FLTARR(3, 3)
;skipped setting some simple values

> float_array
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000

multiple_array[0, 0] = float_array
   1.0000000       2.0000000       3.0000000      0.00000000      0.00000000
   4.0000000       5.0000000       6.0000000      0.00000000      0.00000000
   7.0000000       8.0000000       9.0000000      0.00000000      0.00000000

而这实际上不是我想要的!我的 float_array 不应该覆盖我的多重数组中的其他索引,而应该只覆盖第一个索引 (multiple_array[0, 0])

我想要什么:

我在想这样的事情:

(假设此代码在其他编程语言中可以正常工作)

multiple_array[0, 0] = float_array
   FIRST_FLOAT_ARRAY       0.0000000       0.0000000      0.00000000      0.00000000
   0.0000000               0.0000000       0.0000000      0.00000000      0.00000000
   0.0000000               0.0000000       0.0000000      0.00000000      0.00000000

然后我的 multiple_array 应该是这样的:

> multiple_array
   FIRST_FLOAT_ARRAY       SECOND_FLOAT_ARRAY       THIRD_FLOAT_ARRAY      FOURTH_FLOAT_ARRAY      FIFTH_FLOAT_ARRAY
   SIXTH_FLOAT_ARRAY       0.0000000                0.0000000              0.00000000              0.00000000
   0.0000000               0.0000000                0.0000000              0.00000000              0.00000000

...等等

以后用这个做什么?

稍后我想像这样获取这些值:

current_float_array = multiple_array[0, 0]
> help, current_float_array
CURRENT_FLOAT_ARRAY               FLOAT     = Array[3, 3]

> current_float_array
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000

这可能吗?对我来说,这实际上并不重要,如果我的 multiple_array 会以 PTRARR 或其他任何形式结束,只要我得到像 current_float_array 这样的结果我就会很高兴。

在此先感谢您的帮助! 我期待着任何建议。

我只是自己找到了答案。 这实际上很容易。我也希望这对其他人有帮助。

这是你必须做的:

不用设置/FLOAT,只需在MAKE_ARRAY函数中设置/PTR即可:

multiple_array = MAKE_ARRAY(5, 3, /PTR)
> multiple_array
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>

一如既往地定义您的 float_array

float_array = FLTARR(3, 3)
;skipped setting some simple values

> float_array
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000

最重要的部分:

将你的浮点数组定义为PTR_NEW,这样你就可以将你的浮点数组保存在第一个索引中。

multiple_array[0,0] = PTR_NEW(float_array)
> multiple_array
<PtrHeapVar1><NullPointer><NullPointer><NullPointer><NullPointer>
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>
<NullPointer><NullPointer><NullPointer><NullPointer><NullPointer>

> multiple_array[0,0]
<PtrHeapVar1>

通过在数组前面放置一个 *,您将打印出浮点数组的内容。

> *multiple_array[0,0]
   1.0000000       2.0000000       3.0000000
   4.0000000       5.0000000       6.0000000
   7.0000000       8.0000000       9.0000000

您很好地回答了自己精心设计的问题。 :-) 我可以添加更多选项。

在子数组大小相同 (128x128) 的情况下,IDL 中的一种常见方法是使用更高维的数组来包含其中的几个。在这种情况下,如果您想要子数组的 (5x3) 数组,您可以创建:

multidim_array = FltArr(128, 128, 5, 3)

要访问一个 128x128 子数组,请使用,例如:

current_float_array = multidim_array[*, *, 0, 0]
help, current_float_array
CURRENT_FLOAT_ARRAY               FLOAT     = Array[128, 128]

请注意,如果长度为 1,IDL 会删除 trailing 个维度,因此我们得到 Array[128, 128] 而不是 Array[128, 128, 1, 1]。

效率注意事项:当您将数据 加载到 这个数组时,而不是寻址 128x128 子数组,如果您仅指示起始元素,IDL 会做很多分配更快速。所以,使用:

multidim_array[0, 0, 0, 0] = float_array

而不是:

multidim_array[*, *, 0, 0] = float_array

(一般规则是,在幕后,IDL 获取任何“*”项并将它们扩展为一组索引,用于逐个移动每个数据元素。如果您只给出起始元素, 整个数组可以作为一个块进行复制。)

请注意,这正是您在上面的第一个测试 (multiple_array[0, 0] = float_array) 中无意中所做的,这不是您当时想要的。

当数组非常大时,multidim_array 方法和您的 PtrArr 方法各有利弊,其中内存大小和处理时间可能需要权衡,但在小型应用程序中,任何一种方法都是合理的。

另一种方法(至少自 IDL 8.1 起)是使用 LIST 数据类型, 允许子数组具有不同的大小。事实上,列表的元素可以是任何东西(比如您的子数组),您可以使用简单的数组索引语法访问这些条目(甚至索引到子数组)。以下是您可以执行的操作示例,创建 a 作为列表的列表:

IDL> a=list(list(indgen(2,3),indgen(3,4)), list(indgen(2,4)))
IDL> a
[
    [
        [[0, 1], [2, 3], [4, 5]],
        [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
    ],
    [
        [[0, 1], [2, 3], [4, 5], [6, 7]]
    ]
]
IDL> a[0]
[
    [[0, 1], [2, 3], [4, 5]],
    [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
]
IDL> a[0,1]
       0       1       2
       3       4       5
       6       7       8
       9      10      11

你会像这样在一个循环中将你的数据加载到列表的列表中(抱歉,没有测试,但相信是正确的):

multiple_list = List()
FOR rowI = 0, 3 DO BEGIN
   row_list = List
   FOR columnI = 0, 5 DO $
      row_list.Add, GetYourFloatArrayHerePossiblyUsing(columnI, rowI)
   multiple_list.Add, row_list
ENDFOR ; rowI over all rows

您可以访问第一个数组:

multiple_list[0, 0]

还有:

multiple_list[0, 0, 0, 0]     ; first element of first array
multiple_list[2, 4, 127, 127] ; last element of last array

希望对您有所帮助!