【问题标题】:How to de-interleave array in numpy?如何在numpy中解交错数组?
【发布时间】:2020-10-09 02:01:54
【问题描述】:

我有一个 numpy 数组,它以一种棘手的方式交错,我想不出一个简单的方法来解交错。假设 (84, 132) 矩阵为:

0   100  200 ...
1   101  201 ...
2   102  202 ...
...
83  183  283 ...

我想从第一列每隔四个元素,然后从第二行开始每隔四个元素,然后从第三行开始每隔四个元素,然后从第四行开始每隔四个元素。 (产生四个新列。)然后我想重复第二列,依此类推。所以我想要的 (21, 528) 结果是:

0   1  2  3 100 101 102 103 200 ...
4   5  6  7 104 105 106 107 204 ...
8   9 10 11 108 109 110 111 208 ...
...
80 81 82 83 180 181 182 183 283 ...

我可以通过循环来做到这一点,将 (84, 132) 数组 a 转换为 (21, 528) 数组 b

b = np.zeros(shape=(21, 132*4))
for y in range(0, 21):
  for x in range(0, 132):
    for s in range(0, 4):
      b[y, x * 4 + s] = a[y * 4 + s, x]

有没有更好的方法来使用 numpy 操作来做到这一点?

(上下文:这是 8086 处理器中微码 ROM 的物理排列,我正在尝试解开这些位以进行分析。)

【问题讨论】:

    标签: python arrays numpy numpy-ndarray


    【解决方案1】:

    你可以这样做:

    #!/usr/bin/env python                                                                               
    
    import numpy as np
    
    # construct test data                                                                               
    i = np.arange(132)
    j = np.arange(84)
    ii, jj = np.meshgrid(i, j)
    a = 100 * ii + jj
    
    # the operation                                                                                     
    n0, n1 = a.shape
    m = 4
    b = np.concatenate([a[:,i].reshape((n0 // m, m)) for i in range(n1)], axis=1)
    

    给予:

    >>> a
    array([[    0,   100,   200, ..., 12900, 13000, 13100],
           [    1,   101,   201, ..., 12901, 13001, 13101],
           [    2,   102,   202, ..., 12902, 13002, 13102],
           ...,
           [   81,   181,   281, ..., 12981, 13081, 13181],
           [   82,   182,   282, ..., 12982, 13082, 13182],
           [   83,   183,   283, ..., 12983, 13083, 13183]])
    
    >>> b
    array([[    0,     1,     2, ..., 13101, 13102, 13103],
           [    4,     5,     6, ..., 13105, 13106, 13107],
           [    8,     9,    10, ..., 13109, 13110, 13111],
           ...,
           [   72,    73,    74, ..., 13173, 13174, 13175],
           [   76,    77,    78, ..., 13177, 13178, 13179],
           [   80,    81,    82, ..., 13181, 13182, 13183]])
    

    有点难以看出上面省略了元素的地方发生了什么,所以这里有一个较小的数组 (8x12) 可以显示所有元素的另一种情况

    array([[  0, 100, 200, 300, 400, 500, 600, 700],
           [  1, 101, 201, 301, 401, 501, 601, 701],
           [  2, 102, 202, 302, 402, 502, 602, 702],
           [  3, 103, 203, 303, 403, 503, 603, 703],
           [  4, 104, 204, 304, 404, 504, 604, 704],
           [  5, 105, 205, 305, 405, 505, 605, 705],
           [  6, 106, 206, 306, 406, 506, 606, 706],
           [  7, 107, 207, 307, 407, 507, 607, 707],
           [  8, 108, 208, 308, 408, 508, 608, 708],
           [  9, 109, 209, 309, 409, 509, 609, 709],
           [ 10, 110, 210, 310, 410, 510, 610, 710],
           [ 11, 111, 211, 311, 411, 511, 611, 711]])
    
    array([[  0,   1,   2,   3, 100, 101, 102, 103, 200, 201, 202, 203, 300, 301, 302, 303, 400, 401, 402, 403, 500, 501, 502, 503, 600, 601, 602, 603, 700, 701, 702, 703],
           [  4,   5,   6,   7, 104, 105, 106, 107, 204, 205, 206, 207, 304, 305, 306, 307, 404, 405, 406, 407, 504, 505, 506, 507, 604, 605, 606, 607, 704, 705, 706, 707],
           [  8,   9,  10,  11, 108, 109, 110, 111, 208, 209, 210, 211, 308, 309, 310, 311, 408, 409, 410, 411, 508, 509, 510, 511, 608, 609, 610, 611, 708, 709, 710, 711]])
    

    【讨论】:

    • 我认为不需要连接通常非常昂贵。
    • 谢谢,该解决方案提供了我想要的矩阵。
    • @KenShirriff 我认为它们都有效,但另一种解决方案比我的更有效。我尝试了一个 12000x8000 输入数组,在我的机器上 Divakar 需要 0.6 秒,而我的需要 3 到 4 秒。
    【解决方案2】:

    利用从General idea for nd to nd transformation 借来的想法来排列轴并重塑。 -

    N = 4 # number of rows to split with
    n = a.shape[1]
    a.reshape(-1,N,n).swapaxes(1,2).reshape(-1,n*N)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-05
      • 2019-06-21
      • 2011-06-18
      • 2019-10-20
      • 1970-01-01
      • 2017-02-11
      相关资源
      最近更新 更多