【问题标题】:Numpy: find local co-ordinates within a submatrixNumpy:在子矩阵中查找局部坐标
【发布时间】:2016-10-27 18:05:00
【问题描述】:

假设我们有一个 4x4 矩阵:

A = [[1,2]
     [3,4]]

我们定义另一个矩阵:

C* = [[ 8, 4, 2, 4],
        6, 2, 6, 8],
        4, 2, 6, 4],
        6, 8, 2, 8]]]

接下来我们将 C** 定义为每个 2x2 块的最小值矩阵:

C** = [[2, 2],
       [2, 2]]

我们定义C**和A之间的对应关系: 1.将C**中单元格的值定位到C*中对应的2x2块。 2. 该子块的索引就是A的索引,该子块中最小值的位置就是A中对应的位置。

如何有效地在 A 中找到对应的索引?

【问题讨论】:

  • 你在C* 失去了我。我想知道使用 2x2x2x2 数组是否更容易。
  • @hpaulj 我已经更新了问题以澄清 C* 只是我为说明目的而选择的数字。
  • 那你在问什么? C** 中的值对应于 A 中的什么值?还是 C*?请编辑以阐明映射。
  • 我想我明白了——你把 (1,0) 和 (0,1) 混在一起了。

标签: python arrays numpy matrix


【解决方案1】:

这是一个疯狂的猜测,但也许会有所帮助

您不知道 AB 是什么,但我猜它们是用于索引的。由于numpy 是 0 基数,让我们改为:

In [2010]: B=np.arange(4).reshape(2,2)
In [2011]: B
Out[2011]: 
array([[0, 1],
       [2, 3]])

这是你的C,你想使用 2x2 子矩阵

In [2012]: C
Out[2012]: 
array([[8, 4, 2, 4],
       [6, 2, 6, 8],
       [4, 2, 6, 4],
       [6, 8, 2, 8]])

Reshape 产生 4 个 2x2 数组,但是分组错误

In [2013]: C.reshape(2,2,2,2)
Out[2013]: 
array([[[[8, 4],
         [2, 4]],

        [[6, 2],
         [6, 8]]],


       [[[4, 2],
         [6, 4]],

        [[6, 8],
         [2, 8]]]])

但是 2 个轴的转置会给出正确的子数组

In [2014]: C1=C.reshape(2,2,2,2).transpose(0,2,1,3)
In [2015]: C1
Out[2015]: 
array([[[[8, 4],
         [6, 2]],

        [[2, 4],
         [6, 8]]],


       [[[4, 2],
         [6, 8]],

        [[6, 4],
         [2, 8]]]])

通过重塑为 4x4 来简化事情;所以每一行都是你的子数组

In [2016]: C2=C1.reshape(4,4)
In [2017]: C2
Out[2017]: 
array([[8, 4, 6, 2],
       [2, 4, 6, 8],
       [4, 2, 6, 8],
       [6, 4, 2, 8]])

现在我们可以查找每一行的最小值:

In [2018]: np.argmin(C2,axis=1)
Out[2018]: array([3, 0, 1, 2], dtype=int32)

所以最小值是:

In [2020]: C2[[0,1,2,3],[3,0,1,2]]
Out[2020]: array([2, 2, 2, 2])

[0,1,2,3] 看起来像一个扁平的B[3,0,1,2] 看起来像是重新排序的 A

=====================

在您最初的问题中,您有 A* 和 B*,可以用 tile 和 kron 构建。应用相同的重塑:

In [2029]: B
Out[2029]: 
array([[0, 1],
       [2, 3]])
In [2030]: np.kron(B,np.ones((2,2),int))     # your B*
Out[2030]: 
array([[0, 0, 1, 1],
       [0, 0, 1, 1],
       [2, 2, 3, 3],
       [2, 2, 3, 3]])
In [2031]: np.kron(B,np.ones((2,2),int)).reshape(2,2,2,2).transpose(0,2,1,3).reshape(4,4)
Out[2031]: 
array([[0, 0, 0, 0],
       [1, 1, 1, 1],
       [2, 2, 2, 2],
       [3, 3, 3, 3]])

In [2032]: np.tile(B,(2,2)).reshape(2,2,2,2).transpose(0,2,1,3).reshape(4,4)
Out[2032]: 
array([[0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3],
       [0, 1, 2, 3]])

所以你的 B* 和 A* 映射到我的转置数组的行和列。

======================

C2 argmin 可以用unravel_index 表示为2x2 数组中的坐标:

In [2085]: idx=np.argmin(C2,axis=1)
In [2086]: idx
Out[2086]: array([3, 0, 1, 2], dtype=int32)
In [2094]: idx1=np.unravel_index(idx,(2,2))
In [2095]: idx1
Out[2095]: (array([1, 0, 0, 1], dtype=int32), array([1, 0, 1, 0], dtype=int32))
In [2096]: np.transpose(idx1)
Out[2096]: 
array([[1, 1],
       [0, 0],
       [0, 1],
       [1, 0]], dtype=int32)

将“本地”索引应用于 C1 数组

In [2097]: C1.reshape(4,2,2)[np.arange(4), idx1[0], idx1[1]]
Out[2097]: array([2, 2, 2, 2])

或者没有重塑

In [2100]: idx2=np.unravel_index(np.arange(4),(2,2))
In [2101]: C1[idx2[0],idx2[1], idx1[0], idx1[1]]
Out[2101]: array([2, 2, 2, 2])

【讨论】:

  • 我对第二部分感到困惑。此外,“[0,1,2,3] 看起来像扁平的 B;而 [3,0,1,2] 看起来像重新排序的 A。”是什么意思?那些是A中的坐标吗?它们不可能,因为它们不是局部坐标,它们是基于 C2 的坐标,而不是基于子矩阵的坐标。
  • 我想要 C2 中每个子矩阵的最小值的坐标。这意味着每个最小值的坐标将是 (0,0)、(0,1)、(1,0)、(1,1) 之一。
  • 我添加了使用 np.unravel_index 将这些 4x4 索引转换为 2x2x2x2 的索引。
猜你喜欢
  • 2014-08-17
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多