获取numpy矩阵

时间:2017-11-12 19:52:44

标签: python numpy matrix

给出以下numpy矩阵

import numpy as np
np_matrix = np.array([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0]
                    ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0]
                    ,[0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
                    ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1]
                    ,[0,0,0,1,0,0,0,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0]
                    ,[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]
                    ,[2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]])

print(np_matrix)
print(np_matrix.shape)

可以表示为图像。

enter image description here

以下是关于输入矩阵的一些假设:

  • 矩阵形状可以变化。它不是固定的大小。
  • 正方形的数量因矩阵而异。但矩阵中至少有一个方格。
  • 对于每个绿点,它周围都有一个正方形,正方形内部有一个点。广场内的圆点标有数字2
  • 正方形在X轴上是连续的,正方形的边界从不与其他正方形的边界重叠。正方形边框标有数字1
  • 空格标有数字0

我有两个问题。以最有效的方式,我如何获得具有所有绿点坐标的数组?我怎么能得到一个绿点周围方块的所有角落的阵列?

enter image description here

这是我为这个例子照看的结果:

green_dots_coordinates = [
    [0,0],  # dot 1 with coordinates x1, y1 inside square 1
    [7,12], # dot 2 with coordinates x2, y2 inside square 2
    [16,27],# dot 3 with coordinates x3, y3 inside square 3
    [29,21],# dot 4 with coordinates x4, y4 inside square 4
    [34,7], # dot 5 with coordinates x5, y5 inside square 5
]



sqaures_corners_coordinates = [
    #square nr 1
    [
        [0,6], # x1, y1
        [2,6], # x2, y2
        [0,0], # x3, y3
        [2,0], # x4, y4
    ],

    #square nr 2
    [
        [3,14], # x1, y1
        [9,14], # x2, y2
        [3,7], # x3, y3
        [9,7], # x4, y4
    ],

    #square nr 3
    [
        [12,31], # x1, y1
        [23,31], # x2, y2
        [12,24], # x3, y3
        [23,24], # x4, y4
    ],

    #square nr 4
    [
        [25,22], # x1, y1
        [32,22], # x2, y2
        [25,15], # x3, y3
        [32,15], # x4, y4
    ]

    ,#square nr 5
    [
        [33,13], # x1, y1
        [35,13], # x2, y2
        [33,0], # x3, y3
        [35,0], # x4, y4
    ],

]

2 个答案:

答案 0 :(得分:1)

你的输出格式坦率地说很奇怪,并且需要反转索引的顺序很多,(并且使得输出对索引原始数组毫无用处)但是这样做有效:

def find_boxes(np_matrix):
    np_mat = np_matrix[::-1, :]  # reversed in expected output
    def find_extent(arr, val):
        xn = arr.size
        x0 = np.flatnonzero(arr == 1)
        xi = np.searchsorted(x0, val, side = 'right')
        if xi == x0.size:
            x1 = x0[xi-1]
            x2 = xn - 1
        elif xi == 0:
            x1 = 0
            x2 = x0[xi]
        else:
            x1 = x0[xi-1]
            x2 = x0[xi]
        return np.array([x1, x2])

    green = np.where(np_mat == 2)
    green = tuple(g[np.argsort(green[-1])] for g in green)
    coords = np.empty((green[0].size, 2, 4))

    for i, (x, y) in enumerate(zip(*green)):
        coords[i, 0] =   np.tile(find_extent(np_mat[x, :], y),       2)
        coords[i, 1] = np.repeat(find_extent(np_mat[:, y], x)[::-1], 2)  # reversed again
    return np.stack(green)[::-1].T, coords.swapaxes(1,2).astype(int)
    # reversed again and transposed

测试:

find_boxes(np_matrix)
Out: 
(array([[ 0,  0],
        [ 7, 12],
        [16, 27],
        [29, 21],
        [34,  7]], dtype=int32), 
 array([[[ 0,  6],
         [ 2,  6],
         [ 0,  0],
         [ 2,  0]],

        [[ 3, 14],
         [ 9, 14],
         [ 3,  7],
         [ 9,  7]],

        [[12, 31],
         [23, 31],
         [12, 24],
         [23, 24]],

        [[25, 22],
         [32, 22],
         [25, 15],
         [32, 15]],

        [[33, 13],
         [35, 13],
         [33,  0],
         [35,  0]]]))

答案 1 :(得分:1)

另一种方法,使四个方向对称:

rm = m[::-1].T                            # (j,-i) to (x,y)
green = np.where(rm==2)                   # the costly operation
centers = np.vstack(green).T

rm[green] = 0
res = []

for x,y in centers:
    for s in (-1,1):                      # rear/front
        for t in range(2) :               # vertical/horizontal             
            v = *_,save = rm[x,y::s]            
            v[-1] = 1                     # sentinel
            res.append(y + s*v.argmax())  # find the first 1
            v[-1] = save 
            x,y,rm = y,x,rm.T             # turn 

rm[green] = 2  

coordinates = np.array(res).reshape(-1,4) 
corners = coordinates.take([[1,2],[3,2],[1,0],[3,0]],axis=1)    

这可以避免处理Python切片的包含/排除行为,并使用标记系统管理边界。

print(centers);print(corners)

[[ 0  0]
 [ 7 12]
 [16 27]
 [29 21]
 [34  7]]
-----------
[[[ 0  6]
  [ 2  6]
  [ 0  0]
  [ 2  0]]

 [[ 3 14]
  [ 9 14]
  [ 3  7]
  [ 9  7]]

 [[12 31]
  [23 31]
  [12 24]
  [23 24]]

 [[25 22]
  [32 22]
  [25 15]
  [32 15]]

 [[33 13]
  [35 13]
  [33  0]
  [35  0]]]