Python中如何实现带循环环绕的子序列及多维子网格提取?
问题与解决方案
一、一维场景:循环环绕的子字符串
问题原因
Python 默认切片规则(步长为1时):若起始索引的位置在结束索引之后,切片返回空字符串。比如 str[-7:5] 中,-7 对应的正索引是 len(str)-7,显然大于5,因此结果为空。
解决方案
直接拼接两部分子串:从负索引到字符串末尾的部分,加上从开头到正索引的部分。注意不要用 str 作为变量名,避免和内置类型冲突。
s = "=Hello community of Python=" target = s[-7:] + s[:5] print(target) # 输出: Python==Hell
二、高维场景:循环环绕的子网格(Numpy)
对于N维数组的循环切片,无需手动拆分拼接,利用Numpy的循环填充或数组滚动功能即可高效实现。
1. 二维矩阵示例
以3x3矩阵为例,获取任意中心位置的2x2循环子网格:
import numpy as np m = np.mat('''1 2 3; 4 5 6; 7 8 9''') # 方法1:循环填充数组(将原矩阵在各维度复制一次,扩展为5x5) padded_m = np.tile(m, (2, 2)) # 获取中心(0,0)的2x2子网格 x, y = 0, 0 sub_m = padded_m[x+1:x+3, y+1:y+3] print(sub_m) # 输出: # [[9 7] # [3 1]] # 获取中心(1,0)的2x2子网格 x, y = 1, 0 sub_m = padded_m[x+1:x+3, y+1:y+3] print(sub_m) # 输出: # [[7 8] # [1 2]]
2. 三维数组示例
对于3x3x3的三维数组,同样用循环填充实现:
m3d = np.array(list(range(27))).reshape((3,3,3)) # 三维循环填充,每个维度复制两次,扩展为6x6x6 padded_m3d = np.tile(m3d, (2,2,2)) # 获取目标循环切片 sub_m3d = padded_m3d[2:4, 2:4, 2:4] print(sub_m3d) # 输出: # [[[26 24] # [20 18]] # # [[ 8 6] # [ 2 0]]]
更高效替代方案:使用np.roll
若不想创建大的填充数组,可通过数组滚动调整位置后再切片:
# 二维示例:获取(0,0)中心的2x2子网格 rolled_m = np.roll(np.roll(m, -1, axis=0), -1, axis=1) sub_m = rolled_m[:2, :2] print(sub_m) # 输出[[9,7],[3,1]] # 三维示例:获取目标循环切片 rolled_m3d = np.roll(np.roll(np.roll(m3d, -1, axis=0), -1, axis=1), -1, axis=2) sub_m3d = rolled_m3d[:2, :2, :2] print(sub_m3d) # 目标结果
内容的提问来源于stack exchange,提问作者Tim Kuipers
相关产品推荐
相关产品推荐

