python - 将numpy 2d数组分成相等的部分
问题描述
我有一个 30*30px 的图像,并将其转换为 NumPy 数组。现在我想把这个 30*30 的图像分成 9 个相等的部分(想象一个井字游戏)。我为此目的编写了下面的代码,但我的代码的问题是它有两个嵌套循环,在 python 中,这意味着直接进入低性能城镇(特别是对于大量数据)。那么使用 NumPy 和 Numpy 索引有没有更好的方法呢?
#Factor is saing that the image should be divided into 9 sections 3*3 = 9 (kinda like 3 rows 3 columns)
def section(img , factor = 3):
secs = []
#This basicaly tests if the image can actually get divided into equal sections
if (img.shape[0] % factor != 0):
return False
#number of pixel in each row and column of the sections
pix_num = int(img.shape[0] / factor)
ptr_x_a = 0
ptr_x_b = pix_num -1
for i in range(factor):
ptr_y_a = 0
ptr_y_b = pix_num - 1
for j in range(factor):
secs.append( img[ptr_x_a :ptr_x_b , ptr_y_a : ptr_y_b] )
ptr_y_a += pix_num
ptr_y_b += pix_num
ptr_x_a += pix_num
ptr_x_b += pix_num
return np.array(secs , dtype = "int16")
PS:不介意阅读整个代码,只要知道它使用指针来选择图像的不同区域即可。
解决方案
如果您有一个 shape 数组,您可以使用and(K * M, K * N)
将其转换为某种形状。例如,如果你有,你想转换(K * K, M, N)
reshape
transpose
K = M = N = 3
>>> a = np.arange(81).reshape(9, 9)
进入
[[[ 0, 1, 2],
[ 9, 10, 11],
[18, 19, 20]],
[[ 3, 4, 5],
[12, 13, 14],
[21, 22, 23]],
[[ 6, 7, 8],
[15, 16, 17],
[24, 25, 26]],
...
]]]
这个想法是您需要按照此处显示的顺序(即0, 1, 2, 9, 10, 11, 18, ...
)将元素排列在内存中。您可以通过添加适当的辅助尺寸和转置来做到这一点:
b = a.reshape(K, M, K, N)
c = b.transpose(0, 2, 1, 3)
d = c.reahape(-1, M, N)
作为一个单行:
a.reshape(K, M, K, N).transpose(0, 2 1, 3).reshape(-1, M, N)
转置的顺序决定了块的顺序。前两个维度0, 2
表示您的内部循环迭代列的速度快于行的事实。如果您想按列排列块(更快地迭代行),您可以这样做
c = b.transpose(2, 0, 1, 3)
重塑不会改变元素的内存布局,但必要时转置会复制数据。
在您的特定示例中,K = 3
并且M = N = 10
. 除此之外,上面的代码没有任何变化。
顺便说一句,可以通过将范围直接设置在您想要的索引上而不是辅助量以及预先分配输出来改进循环:
result = np.zeros(factor * factor, pix_num, pix_num)
n = 0
for r in range(0, img.shape[0], pix_num):
for c in range(0, img.shape[1], pix_num):
result[n, :, :] = img[r:r + pix_num, c:c + pix_num]
n += 1
推荐阅读
- octave - gnu八度中gnu的含义?
- html - 设置默认值
基于列表的布尔条件 - networking - 使用 url 单独调节流量
- arrays - 如何添加从 c 中的文件编号读取的二维数组组?
- sql - 加入 2 个不同大小的数组
- typescript - 如何访问 `setup` 的内部状态而不通过`data` 暴露它?
- c# - 无法通过实体框架查询 SQL Server“没有为此 DbContext 配置数据库提供程序”
- apache-spark - 将具有 oracle blob 列的 spark-sql 转换为 java byte[] 的问题
- php - Mysql 行号的顺序非常慢
- javascript - 输入日期日历打不开