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

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

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

  1. ↓-------<------S <- start
  2. >------->------↓
  3. ↓-------<------<
  4. >------->------E <- end

比如说

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

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

  1. import numpy as np
  2. def unzigzag(z, numcols):
  3. numrows = len(z) // numcols
  4. a = np.zeros((numrows, numcols))
  5. col = numcols - 1
  6. row = 0
  7. sign = -1
  8. for i in range(numrows*numcols):
  9. if col == -1:
  10. col = 0
  11. sign = 1
  12. row += 1
  13. if col == numcols:
  14. col = numcols - 1
  15. sign = -1
  16. row += 1
  17. a[row, col] = z[i]
  18. col += sign
  19. return a
  20. A = [4, 3, 2, 1, 5, 6, 7, 8, 12, 11, 10, 9]
  21. B = unzigzag(A, 4)
  22. #[[ 1. 2. 3. 4.]
  23. # [ 5. 6. 7. 8.]
  24. # [ 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维情况的示例:

  1. import numpy as np
  2. def unzigzag3(z, numcols):
  3. numrows = z.shape[0] // numcols
  4. new_shape = (numrows, numcols) + z.shape[1:]
  5. a = np.zeros(new_shape)
  6. col = numcols - 1
  7. row = 0
  8. sign = -1
  9. for i in range(numrows*numcols):
  10. if col == -1:
  11. col = 0
  12. sign = 1
  13. row += 1
  14. if col == numcols:
  15. col = numcols - 1
  16. sign = -1
  17. row += 1
  18. a[row, col, :] = z[i, :]
  19. col += sign
  20. return a
  21. 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]])
  22. print(A.shape) # (12, 2)
  23. B = unzigzag3(A, 4)
  24. print(B)
  25. print(B.shape) # (3, 4, 2)
33qvvth1

33qvvth11#

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

  1. import numpy as np
  2. a = np.array([4, 3, 2, 1, 5, 6, 7, 8, 12, 11, 10, 9])
  3. numcols = 4
  4. a = a.reshape(-1,numcols)
  5. a[::2] = np.flip(a, axis=1)[::2]
  6. print(a)

输出量

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

8gsdolmq2#

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

  1. import numpy as np
  2. def unzigzag(z, numcols):
  3. new_shape = (z.shape[0] // numcols, numcols) + z.shape[1:]
  4. a = z.copy().reshape(new_shape)
  5. a[::2] = np.flip(a, axis=1)[::2]
  6. return a
  7. unzigzag(np.array([4, 3, 2, 1, 5, 6, 7, 8, 12, 11, 10, 9]), numcols=4)
  8. # [[ 1 2 3 4]
  9. # [ 5 6 7 8]
  10. # [ 9 10 11 12]]
  11. # shape: (3, 4)
  12. 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)
  13. # [[[ 1 1]
  14. # [ 2 2]
  15. # [ 3 3]
  16. # [ 4 4]]
  17. # [[ 5 5]
  18. # [ 6 6]
  19. # [ 7 7]
  20. # [ 8 8]]
  21. # [[ 9 9]
  22. # [10 10]
  23. # [11 11]
  24. # [12 12]]]
  25. # shape: (3, 4, 2)
展开查看全部

相关问题