0

知道向量的多维数组的形状,我们如何将其转换为一维的新向量(通过展平多维数组)?

例如考虑以下数组:

arr = [
  [
    [ nil, nil ],
    [ nil, nil ],
    [ nil, nil ]
  ],
  [
    [ nil, nil ],
    [ nil, nil ],
    [ nil, nil ]
  ]
]

arr[0][0][0] = "A"
arr[1][0][1] = "B"

arr # =>
[
  [
    [ "A", nil ],
    [ nil, nil ],
    [ nil, nil ]
  ],
  [
    [ nil, "B" ],
    [ nil, nil ],
    [ nil, nil ]
  ]
]

...向量A的起点和B终点在哪里。可以写:

shape  = [2, 3, 2]
vector = [1, 0, 1]

从现在开始,假设我们 flatten arr,我们如何翻译向量呢?换句话说,如何将这个 3 维向量转换为新的 1 维向量?

这是一种特殊情况,因为向量的原点也是数组的第一个坐标。所以我们可以找到结果:

arr.flatten.index("B") # => 7

这是另一个二维数组的例子:

arr = [
  [ "A", nil ],
  [ "B", nil ],
  [ nil, nil ],
  [ nil, nil ],
  [ nil, nil ]
]

我们可以这样写:

shape  = [2, 5]
vector = [1, 0]

而且,再一次,

arr.flatten.index("B") # => 2

但这里有一个更复杂的例子,带有一个负向量:

arr = [
  [ "B", nil ],
  [ "A", nil ],
  [ nil, nil ],
  [ nil, nil ],
  [ nil, nil ]
]

shape  = [2, 5]
vector = [-1, 0]

下面的方法怎么写?

vector2index(shape, vector) # => -2

一维数组的示例(简单):

arr = [ nil, "B", nil, nil, "A", nil, nil ]

shape  = [7]
vector = [-3]
vector2index(shape, vector) # => -3

有没有一种简单的方法可以从任意维度的数组中扁平化一个向量?谢谢。

4

1 回答 1

0

首先,假设数组的第一个元素用于 X 轴,第二个 - 用于 Y 轴,第三个 - 用于 Z 轴,您在第二个和第三个示例中存在错误。第三个例子应该是

shape  = [2,5]
vector = [0,-1]
vector2index(shape, vector) # => -2

如果数组的第一个元素用于 Y 轴,第二个元素用于 X 轴,则第二个和第三个示例是正确的,但第一个示例是错误的。

如果我正确理解了这个想法,我们需要在第一个示例中乘以vector[1]shape[0]乘以vector[2]shape[0]*shape[1]然后计算 3 个元素的总和。一般来说,我们不需要将第0个元素相乘,我们需要将第n个元素相乘shape[0]*shape[1]*...*shape[n-1]

你可以这样实现它:

vector.each_with_index.map { 
  |v, i| i == 0? v: v * shape[0..i-1].inject(:*) 
}.inject(:+)

更新。更新问题后,它变得更加清晰。如果要保留 Ruby 的索引顺序,则需要反转数组shapevector.

vector.reverse.each_with_index.map { 
  |v, i| i == 0? v: v * shape[0..i-1].reverse.inject(:*) 
}.inject(:+)
于 2012-05-01T00:59:34.687 回答