【问题标题】:Matrix to Vector with python/numpy矩阵到向量与 python/numpy
【发布时间】:2016-09-11 21:03:35
【问题描述】:

如果我需要通过按行或按列读取来创建向量,Numpy ravel 效果很好。但是,我想通过使用图像处理中经常使用的方法将矩阵转换为一维数组。这是一个初始矩阵A 和最终结果B 的示例:

A = np.array([[ 0,  1,  2,  3],
              [ 4,  5,  6,  7],
              [ 8,  9, 10, 11],
              [12, 13, 14, 15]])

B = np.array([[ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15])

是否有现有的功能可以帮助我解决这个问题?如果没有,你能给我一些关于如何解决这个问题的提示吗? PS。矩阵ANxN

【问题讨论】:

  • 所以它是一个锯齿形对角线横向?有技术名称吗?目的是什么?

标签: python numpy


【解决方案1】:

我用numpy好几年了,从来没见过这样的功能。

这是您可以做到的一种方法(不一定是最有效的):

In [47]: a
Out[47]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

In [48]: np.concatenate([np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])])
Out[48]: array([ 0,  1,  4,  8,  5,  2,  3,  6,  9, 12, 13, 10,  7, 11, 14, 15])

将单行分解为单独的步骤:

a[::-1, :] 反转行:

In [59]: a[::-1, :]
Out[59]: 
array([[12, 13, 14, 15],
       [ 8,  9, 10, 11],
       [ 4,  5,  6,  7],
       [ 0,  1,  2,  3]])

(也可以写成a[::-1]np.flipud(a)。)

np.diagonal(a, k) 提取kth 对角线,其中k=0 是主对角线。所以,例如,

In [65]: np.diagonal(a[::-1, :], -3)
Out[65]: array([0])

In [66]: np.diagonal(a[::-1, :], -2)
Out[66]: array([4, 1])

In [67]: np.diagonal(a[::-1, :], 0)
Out[67]: array([12,  9,  6,  3])

In [68]: np.diagonal(a[::-1, :], 2)
Out[68]: array([14, 11])

在列表推导中,k 给出了要提取的对角线。我们想要反转每隔一个对角线中的元素。表达式 2*(k % 2) - 1 给出的值是 1、-1、1、...,因为 k 从 -3 到 3 不等。使用 [::1] 进行索引使被索引的数组的顺序保持不变,而使用 [::-1] 进行索引反转数组的顺序。所以np.diagonal(a[::-1, :], k)[::(2*(k % 2)-1)] 给出了kth 对角线,但所有其他对角线都颠倒了:

In [71]: [np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])]
Out[71]: 
[array([0]),
 array([1, 4]),
 array([8, 5, 2]),
 array([ 3,  6,  9, 12]),
 array([13, 10,  7]),
 array([11, 14]),
 array([15])]

np.concatenate() 将它们全部放入一个数组中:

In [72]: np.concatenate([np.diagonal(a[::-1,:], k)[::(2*(k % 2)-1)] for k in range(1-a.shape[0], a.shape[0])])
Out[72]: array([ 0,  1,  4,  8,  5,  2,  3,  6,  9, 12, 13, 10,  7, 11, 14, 15])

【讨论】:

    【解决方案2】:

    我发现了关于 MATLAB 之字形扫描的讨论,但对 numpy 的讨论不多。一个项目似乎对 8x8 块使用硬编码索引数组

    https://github.com/lot9s/lfv-compression/blob/master/scripts/our_mpeg/zigzag.py

    ZIG = np.array([[0,  1,  5,  6,  14, 15, 27, 28],
                   [2,  4,  7,  13, 16, 26, 29, 42],
                   [3,  8,  12, 17, 25, 30, 41, 43],
                   [9,  11, 18, 24, 31, 40, 44,53],
                   [10, 19, 23, 32, 39, 45, 52,54],
                   [20, 22, 33, 38, 46, 51, 55,60],
                   [21, 34, 37, 47, 50, 56, 59,61],
                   [35, 36, 48, 49, 57, 58, 62,63]])
    

    显然它使用了 jpeg 和 mpeg 压缩。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 2017-11-18
      相关资源
      最近更新 更多