Python 如何以矢量化的方式向numpy二维矩阵添加掩蔽噪声?
我有一个numpy二维阵列Python 如何以矢量化的方式向numpy二维矩阵添加掩蔽噪声?,python,numpy,vectorization,Python,Numpy,Vectorization,我有一个numpy二维阵列X,形状(n个样本,n个特征)。我想对每个样本(即每行)应用掩蔽噪声。基本上,对于每一行条目,我想随机选择全部n_特征元素的一部分frac,并将它们设置为0 到目前为止,我已经对循环的内部进行了矢量化,但无法摆脱外部I循环 我目前的代码如下 def add_noise(X, frac): X_noise = X.copy() n_samples = X.shape[0] n_features = X.shape[1] for i in
X
,形状(n个样本,n个特征)
。我想对每个样本(即每行)应用掩蔽噪声。基本上,对于每一行条目,我想随机选择全部n_特征
元素的一部分frac
,并将它们设置为0
到目前为止,我已经对循环的内部进行了矢量化,但无法摆脱外部I
循环
我目前的代码如下
def add_noise(X, frac):
X_noise = X.copy()
n_samples = X.shape[0]
n_features = X.shape[1]
for i in range(n_samples):
mask = np.random.randint(0, n_features, int(frac * n_features))
X_noise[i][mask] = 0
return X_noise
下面是一个例子
test_arr = np.arange(1, 11)
test_arr = np.array([test_arr, test_arr])
print(test_arr)
print(add_noise(test_arr, 0.3))
[[ 1 2 3 4 5 6 7 8 9 10]
[ 1 2 3 4 5 6 7 8 9 10]]
[[ 1 0 3 4 5 6 0 8 9 0] # 0.3 * num_features = 3 random elements
[ 0 2 3 4 5 6 7 0 0 10]] # for each row set to 0
如何摆脱外部循环?没有什么可以阻止您使用生成完整的索引矩阵,每行一个元素:
k = int(frac * n_features)
indices = np.random.randint(0, n_features, size=(n_samples, k))
X_noise[np.arange(n_samples)[:, None], indices] = 0
索引np.arange(n_samples)[:,None]
使范围广播到shapen_samples,k
。这种方法的优点是不需要带遮罩的中间步骤
这种方法存在两个潜在问题:
k=int(分形*n_特征)
不一定是与您要查找的实际分数最接近的整数。更像是k=math.round(frac*n\u特性)
np.random.randint
替换样本。这意味着您偶尔会在索引中的同一行上遇到冲突。如果你同意的话,没关系。如果没有,您可以使用进行取样,而无需更换。问题是,然后必须逐个循环每一行frac
处对它们设置阈值,这样您的总体噪声接近frac
,但每行中的噪声都是随机的。这些数字可以通过以下方式生成:
X_噪声[np.random.sample(size=X_噪声.shape)
尝试创建0和1的映射,并将测试数组与映射相乘:
zero_map = np.round(np.random.rand(*test_arr.shape) * (1-frac))
test_arr = test_arr * zero_map
可以使用numpy函数沿_轴应用_
def add_noise(X, frac):
X_noise = X.copy()
n_samples = X.shape[0]
n_features = X.shape[1]
mask = np.concatenate((np.ones((n_samples,int(frac * n_features)), dtype=np.bool),
np.zeros((n_samples, n_features - int(frac * n_features)), dtype=np.bool)),
axis=1)
np.apply_along_axis(np.random.shuffle,1,mask)
X_noise[mask] = 0
return X_noise
您是否需要控制
n\u功能
dimension?@norok2您能详细说明一下吗?如果您的意思是将元素数设置为0,那么是。否,我的意思是,如果您需要为每个n_特征使用不同的frac
值,则所有样本的frac
值都相同。确定。然后注意,如果在randint()
中重复某些索引,代码也可能失败。您可能想改用np.random.choice()
或者直接使用掩码:test\u arr[~mask]=0
是否可以使用np.random.choice(…)
从[0,num_features)
?然后方法将几乎保持不变。@pmcarpan。此时,您必须执行以下操作
def add_noise(X, frac):
X_noise = X.copy()
n_samples = X.shape[0]
n_features = X.shape[1]
mask = np.concatenate((np.ones((n_samples,int(frac * n_features)), dtype=np.bool),
np.zeros((n_samples, n_features - int(frac * n_features)), dtype=np.bool)),
axis=1)
np.apply_along_axis(np.random.shuffle,1,mask)
X_noise[mask] = 0
return X_noise