Numpy:在子矩阵中找到局部坐标

时间:2016-10-27 18:05:00

标签: python arrays numpy matrix

假设我们有一个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?

中有效地找到相应的索引

1 个答案:

答案 0 :(得分:0)

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

你不是AB是什么,但我猜他们是指索引。由于numpy为0 base,因此请更改为:

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]])

重塑产生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)

将'local'索引应用于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])