python - Python数组,如何在没有循环的情况下选择一定距离后的一组列和行
问题描述
我想从一个大的二维数组中选择某些列和行。例如,我想N = 64
在每D = 128
列之后选择列,如果我的大数组具有 shape (384,384)
,这将导致更小的(256, 256)
矩阵,主要是因为我想从大矩阵中删除冗余数据。
我的代码如下所示,问题是我不知道如何在不使用循环的情况下以一种很好的方式避免显式索引(这里每个方向 4 次,实际上可以实现为具有通用大小的循环)。同样在这个例子中,我从 0 列开始选择,通常它可以从任意列开始。
row_mask = np.zeros(rows, dtype=bool) # e.g. rows = 384
col_mask = np.zeros(cols, dtype=bool) # e.g. cols = 384
N = 64
D = 128
# explicit selection of columns and rows
row_mask[0:N] = 1
row_mask[D:D + N] = 1
row_mask[D * 2:D * 2 + N] = 1
row_mask[-N:] = 1
col_mask[0:N] = 1
col_mask[D:D + N] = 1
col_mask[D * 2:D * 2 + N] = 1
col_mask[-N:] = 1
#Image of (384, 384), image of (256, 256)
image = Image[np.ix_(row_mask, col_mask)]
解决方案
实际上,对于这个具有相对较大图块的示例,在 for 循环中使用切片比通过更昂贵的花式索引避免 for 循环更有效:
from scipy.misc import face
from timeit import timeit
img = face()
def fancy():
D,N=128,64
r_mask = np.arange(img.shape[0]) % D < N
c_mask = np.arange(img.shape[1]) % D < N
return img[r_mask[:, None] & c_mask].reshape(np.count_nonzero(r_mask), np.count_nonzero(c_mask),3)
def loopy():
di,dj=64,64
DI,DJ=128,128
return np.block([[[img[i:i+di,j:j+dj]] for j in range(0,img.shape[1],DJ)] for i in range(0,img.shape[0],DI)])
(fancy()==loopy()).all()
# True
timeit(loopy,number=100)*10
# 0.763049490051344
timeit(fancy,number=100)*10
# 5.845791429746896
推荐阅读
- apache - 虚拟主机的端口转发
- python - df.append() 未附加到 DataFrame
- c# - 将 WCF 服务中使用的实体框架连接字符串包含到自托管控制台应用程序中的正确方法是什么?
- javascript - 在布局页面中添加 document.ready 后,包含 document.ready 函数的视图中的脚本标记未命中
- ios - App Store Connect 操作错误:配置文件无效...请使用与团队 ID“XX..XX”关联的配置文件
- javascript - 当我用 jQuery 点击另一个元素时隐藏元素
- terraform - 使用模块时 Terraform 根目录中 variables.tf 的用途是什么?
- python - 如何用相似行列表中的值快速填充一行中的 NaN 值
- angular - 订阅运行时如何绘制不完整的组件?
- python-3.x - 将警告转换为失败:ResourceWarning:未关闭
在为使用套接字的代码编写测试时,我有时会得到
ResourceWarning: unclosed <socket.socket ...
我真的很喜欢,因为它促使我在代码中故意关闭套接字。
但是,如果发生这种情况,测试实际上失败了,而不是仅仅在控制台中显示警告,