Python中如何为矩阵的行/列选取操作添加选择噪声
实现方案
核心逻辑是为矩阵的每一列独立生成目标行邻域内的随机行索引,通过numpy高级索引批量取值,最终得到和单行选取维度完全一致、每个列位置独立从邻域行采样的带噪声结果。
依赖说明
矩阵操作使用numpy实现,向量化运算效率远高于原生Python列表循环,首先导入依赖:
import numpy as np
完整实现代码
带噪声行选取函数
def noisy_row_select(m, target_row, noise_half_width=2): """ 带随机位置噪声的行选取 参数说明: - m: 二维numpy格式矩阵 - target_row: 基准目标行索引,常规无噪声选行时的目标行号 - noise_half_width: 噪声半宽,默认值2表示每个列位置从目标行上下各2行(共5行)范围内随机取值 返回值: 长度等于矩阵列数的一维数组,和常规m[target_row, :]返回维度一致 """ row_count, col_count = m.shape # 自动裁剪索引范围,避免行号越界 valid_row_min = max(0, target_row - noise_half_width) valid_row_max = min(row_count - 1, target_row + noise_half_width) # 为每个列独立生成随机行索引 rand_row_idx = np.random.randint(low=valid_row_min, high=valid_row_max + 1, size=col_count) col_idx = np.arange(col_count) # 高级索引批量取值 return m[rand_row_idx, col_idx]
示例验证(匹配给出的测试用例)
# 参考用4x4测试矩阵 m = np.array([ [1,2,3,4], [5,6,7,8], [9,1,2,3], [4,5,6,7] ]) # 目标行索引为2,噪声半宽设为1(即候选行是1、2、3三行,匹配示例取值范围) noisy_result = noisy_row_select(m, target_row=2, noise_half_width=1) print(noisy_result)
多次运行上述代码,会随机得到不同的采样结果,其中某一次运行的输出就会是举例的[4 7 1 6]。
扩展说明
- 边界自动适配:当目标行靠近矩阵首行/末行时,函数会自动裁剪非法索引范围,不会触发索引越界错误。比如目标行是0(矩阵第一行),噪声半宽设为2时,采样范围会自动调整为0、1、2三行。
- 带噪声列选取:逻辑和行选取完全对称,只需互换行列索引逻辑即可,实现参考:
def noisy_col_select(m, target_col, noise_half_width=2): row_count, col_count = m.shape valid_col_min = max(0, target_col - noise_half_width) valid_col_max = min(col_count - 1, target_col + noise_half_width) rand_col_idx = np.random.randint(low=valid_col_min, high=valid_col_max + 1, size=row_count) row_idx = np.arange(row_count) return m[row_idx, rand_col_idx]
- 自定义采样权重:如果不想让邻域内所有行被选中的概率均等,可以替换随机索引生成逻辑,比如给离目标行更近的位置更高的采样权重:
# 示例:噪声半宽为2时,偏移-2/-1/0/1/2的采样概率分别为0.1/0.2/0.4/0.2/0.1,越靠近目标行概率越高 offsets = np.arange(-noise_half_width, noise_half_width + 1) sample_prob = np.array([0.1, 0.2, 0.4, 0.2, 0.1]) # 过滤越界的偏移值 valid_mask = (target_row + offsets >= 0) & (target_row + offsets < row_count) valid_offsets = offsets[valid_mask] valid_prob = sample_prob[valid_mask] valid_prob = valid_prob / valid_prob.sum() # 概率归一化 # 生成带权重的随机偏移 rand_offsets = np.random.choice(valid_offsets, size=col_count, p=valid_prob) rand_row_idx = target_row + rand_offsets
内容的提问来源于stack exchange,提问作者Typo
相关产品推荐
相关产品推荐

