求满足边界、等间距、对称条件的Numpy数组切片step通用方法
对称等间距Numpy数组的有效切片步长求解
问题定义
给定由np.linspace(-M, M, N)生成的对称等间距数组(M为正实数,N为元素总数),需找出所有满足以下条件的切片步长step:
- 保留数组的最小值(-M)和最大值(M)
- 切片后元素保持等间距(由切片步长天然保证)
- 切片结果关于0对称,且不含0元素
示例验证
- 当
N=11(数组为np.linspace(-10,10,11)):有效步长为2,切片结果[-10, -6, -2, 2, 6, 10]符合所有条件 - 当
N=21(数组为np.linspace(-10,10,21)):有效步长为4和20,切片结果分别为[-10,-6,-2,2,6,10]和[-10,10],均满足要求
数学公式推导
索引特性分析
原数组索引范围为0到N-1:
- 最小值对应索引
0,最大值对应索引N-1 - 若
N为奇数,0元素对应索引k0 = (N-1)//2;若N为偶数,数组本身不含0元素
约束条件转化
- 保留边界:步长
step必须满足(N-1) % step == 0,即step是D = N-1的正因数(保证索引N-1能被切片选中) - 不含0且对称:
- 若
N为奇数:step必须不能整除k0(避免选中0元素的索引) - 若
N为偶数:只需满足边界约束即可(原数组无0,切片后天然保持对称无0)
- 若
有效步长集合
- 当
N为偶数:所有D = N-1的正因数(若需排除原数组,取step>1) - 当
N为奇数:所有D = N-1的正因数中,**不能整除k0=(N-1)//2**的数(同样可排除step=1)
有效切片方式的数量
- 计算
D=N-1的正因数总数,记为count_D - 若
N为奇数:计算k0=(N-1)//2的正因数中同时是D因数的数量,记为count_k0;有效数量为count_D - count_k0 - 若
N为偶数:有效数量等于count_D(排除原数组则减1)
代码实现
import math def get_valid_steps(N): D = N - 1 # 生成一个数的所有正因数 def get_divisors(n): divisors = set() for i in range(1, int(math.isqrt(n)) + 1): if n % i == 0: divisors.add(i) divisors.add(n // i) return sorted(divisors) divisors_D = get_divisors(D) valid_steps = [] if N % 2 == 1: # 原数组含0,排除能整除k0的因数 k0 = (N - 1) // 2 divisors_k0 = get_divisors(k0) valid_steps = [s for s in divisors_D if s not in divisors_k0] else: # 原数组不含0,所有D的因数均有效 valid_steps = divisors_D # 可选:排除步长1(即原数组),仅保留缩减后的切片方式 # valid_steps = [s for s in valid_steps if s > 1] return valid_steps # 测试用例 print(get_valid_steps(11)) # 输出: [2, 10] print(get_valid_steps(21)) # 输出: [4, 20] print(get_valid_steps(314)) # 输入N=314(偶数),输出D=313的所有因数(313是质数,所以输出[1, 313])
内容的提问来源于stack exchange,提问作者btypoon
相关产品推荐
相关产品推荐

