numpy 将数组反锯齿形化为矩阵

xqkwcwgp  于 2022-12-04  发布在  其他
关注(0)|答案(2)|浏览(114)

我有一个1D数组,它实际上是一个2D矩阵,采样方式如下:

↓-------<------S  <- start
>------->------↓
↓-------<------<
>------->------E  <- end

比如说

B =    1 2  3  4
       5 6  7  8
       9 10 11 12

编码为A = [4, 3, 2, 1, 5, 6, 7, 8, 12, 11, 10, 9]
列数可以是奇数或偶数。
下面的代码可以工作,但由于循环(并且没有矢量化),效率很低。如何做一个更有效的Numpy“unzigoraging”?

import numpy as np

def unzigzag(z, numcols):
    numrows = len(z) // numcols
    a = np.zeros((numrows, numcols))
    col = numcols - 1
    row = 0
    sign = -1
    for i in range(numrows*numcols):
        if col == -1:
            col = 0
            sign = 1
            row += 1
        if col == numcols:
            col = numcols - 1
            sign = -1
            row += 1
        a[row, col] = z[i]
        col += sign
    return a    

A = [4, 3, 2, 1, 5, 6, 7, 8, 12, 11, 10, 9]
B = unzigzag(A, 4)
#[[ 1.  2.  3.  4.]
# [ 5.  6.  7.  8.]
# [ 9. 10. 11. 12.]]

如果可能的话,即使维度多于1D:

  • 如果A具有形状(12, ),则unzigzag(A, numcols=4)具有形状(3,4)
  • 如果A形状为(12, 100),则unzigzag(A, numcols=4)的形状为(3,4,100)
  • 如果A形状为(n, i, j, k, ...),则unzigzag(A, numcols)的形状为(n/numcols, numcols, i, j, k, ...)

编辑:n维情况的示例:

import numpy as np

def unzigzag3(z, numcols):
        numrows = z.shape[0] // numcols
        new_shape = (numrows, numcols) + z.shape[1:]
        a = np.zeros(new_shape)
        col = numcols - 1
        row = 0
        sign = -1
        for i in range(numrows*numcols):
            if col == -1:
                col = 0
                sign = 1
                row += 1
            if col == numcols:
                col = numcols - 1
                sign = -1
                row += 1
            a[row, col, :] = z[i, :]
            col += sign
        return a    

A = np.array([[4,4], [3, 3], [2, 2], [1, 1], [5, 5], [6, 6], [7, 7], [8, 8], [12, 12], [11, 11], [10, 10], [9, 9]])
print(A.shape)  # (12, 2)
B = unzigzag3(A, 4)
print(B) 
print(B.shape) # (3, 4, 2)
33qvvth1

33qvvth11#

我会重新调整形状,然后每隔一行用该行的水平翻转版本更新一次。

import numpy as np

a = np.array([4, 3, 2, 1, 5, 6, 7, 8, 12, 11, 10, 9])
numcols = 4

a = a.reshape(-1,numcols)
a[::2] = np.flip(a, axis=1)[::2]

print(a)

输出量

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
8gsdolmq

8gsdolmq2#

根据@Chris的回答(完全归功于他),这里似乎有一个适用于一维和n维输入的工作版本:

import numpy as np

def unzigzag(z, numcols):
    new_shape = (z.shape[0] // numcols, numcols) + z.shape[1:]
    a = z.copy().reshape(new_shape)
    a[::2] = np.flip(a, axis=1)[::2]
    return a

unzigzag(np.array([4, 3, 2, 1, 5, 6, 7, 8, 12, 11, 10, 9]), numcols=4)

# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
# shape: (3, 4)

unzigzag(np.array([[4,4], [3, 3], [2, 2], [1, 1], [5, 5], [6, 6], [7, 7], [8, 8], [12, 12], [11, 11], [10, 10], [9, 9]]), numcols=4)

# [[[ 1  1]
#   [ 2  2]
#   [ 3  3]
#   [ 4  4]]

#  [[ 5  5]
#   [ 6  6]
#   [ 7  7]
#   [ 8  8]]

#  [[ 9  9]
#   [10 10]
#   [11 11]
#   [12 12]]]
# shape: (3, 4, 2)

相关问题