如何按百分比重叠分割数组?NumPy数组分块函数实现需求
解决按块数与重叠率分割NumPy数组列的问题
我来帮你实现这个按指定块数和重叠百分比分割NumPy数组每列的函数,下面一步步拆解需求并给出代码:
核心逻辑推导
要实现这个功能,我们需要先明确几个关键参数的计算方式:
- 窗口大小(window_size):每个块包含的元素数量,由列长度、目标块数和重叠率共同决定。公式推导:
假设列长度为n,目标块数为k,重叠率为p(0≤p<1),那么k个块覆盖的总元素长度为:window_size + (k-1)*window_size*(1-p) ≤ n
整理后得到窗口大小的计算方式:window_size = n // [1 + (k-1)*(1-p)] - 步长(step):相邻两个块起始位置的间隔,等于窗口大小减去重叠部分的长度:
step = int(window_size*(1-p)) - 有效起始索引:确保每个块的结束位置不超过列的长度,即
start + window_size ≤ n
完整代码实现
import numpy as np def split_columns_by_blocks(arr, num_blocks, overlap_percent): """ 将二维NumPy数组的每一列按指定块数和重叠百分比分割为多个块 参数: arr: 输入的二维NumPy数组 num_blocks: 目标分割的块数(正整数) overlap_percent: 重叠百分比,范围0到1(不包含1) 返回: 列表,每个元素对应原数组一列的分割结果(二维NumPy数组) """ # 输入合法性检查 if not isinstance(arr, np.ndarray) or arr.ndim != 2: raise ValueError("输入必须是二维NumPy数组") if not isinstance(num_blocks, int) or num_blocks <= 0: raise ValueError("块数必须是正整数") if not (0 <= overlap_percent < 1): raise ValueError("重叠百分比必须在[0, 1)范围内") split_results = [] # 遍历每一列 for col in arr.T: col_length = len(col) # 特殊情况:只需要1个块,直接返回整列 if num_blocks == 1: split_results.append(np.array([col])) continue # 计算窗口大小 denominator = 1 + (num_blocks - 1) * (1 - overlap_percent) window_size = int(col_length // denominator) # 窗口大小为0,说明列太短无法分割,返回空列表 if window_size == 0: split_results.append(np.array([])) continue # 计算步长 step = int(window_size * (1 - overlap_percent)) # 处理步长为0的极端情况(重叠率接近100%) if step == 0: step = 1 # 生成所有有效的起始索引 valid_starts = [i * step for i in range(num_blocks) if i * step + window_size <= col_length] # 截取每个块并转换为数组 column_blocks = np.array([col[start:start+window_size] for start in valid_starts]) split_results.append(column_blocks) return split_results
测试示例
用你提供的输入数组测试一下:
# 测试输入 test_arr = np.array([[3, 7],[5, 8],[6, 19],[8, 59],[10, 42],[12, 54], [13, 32], [14, 19], [99, 19]]) # 按3块、50%重叠分割 result = split_columns_by_blocks(test_arr, num_blocks=3, overlap_percent=0.5) # 打印第1列的分割结果 print("第1列分割结果:") print(result[0]) # 输出: # [[ 3 5 6 8] # [ 6 8 10 12] # [10 12 13 14]] # 打印第2列的分割结果 print("\n第2列分割结果:") print(result[1]) # 输出: # [[ 7 8 19 59] # [19 59 42 54] # [42 54 32 19]]
边界情况说明
- 当
num_blocks=1时,直接将整列作为一个块返回 - 当列长度不足以分割出指定块数时,对应列的分割结果为空数组
- 当重叠百分比接近100%(步长为0)时,自动将步长设为1,避免死循环
内容的提问来源于stack exchange,提问作者mak
相关产品推荐
相关产品推荐

