我有一个
n x n
矩阵,其中每一行都是来自 1 to n
的整数的排列。
对于给定的整数 k in {1,2,...,n}
,我的目标是在每行中找到 k
并将其删除,以便每行中的剩余元素保持原始顺序。
为了具体起见,假设
X
是该矩阵,而 n = 5
。
import numpy as np
X= np.array([
[4, 3, 5, 1, 2],
[5, 3, 2, 1, 4],
[3, 2, 4, 1, 5],
[2, 4, 3, 5, 1],
[3, 5, 2, 1, 4]
])
对于
k = 1
,我希望输出为:
X = np.array([
[4, 3, 5, 2],
[5, 3, 2, 4],
[3, 2, 4, 5],
[2, 4, 3, 5],
[3, 5, 2, 4]
])
有没有一种方法可以删除
k
并与 m
很好地缩放?
目前,我创建了一个掩码,用于标识
X
的每一行中不等于 k
的条目。这样,mask[i]
为我提供了一个布尔数组,对于第 True
行中不等于 i
的元素,该数组为 k
。
接下来,我将掩码应用于每一行:迭代每一行并使用
X[i][mask[i]]
过滤掉每行中的值 k
。然后将每行的结果分配给 Xnew
中的相应行。
m = 5
n = m
X = np.array([np.random.permutation(np.arange(1, n + 1)) for _ in range(m)])
k = 1
mask = X != k
Xnew = np.zeros([n,m-1])
for i in range(m):
Xnew[i]=X[i][mask[i]]
此方法适用于小矩阵,但由于每行上的循环,可能无法很好地适应较大的矩阵。我想知道是否有更有效的方法来实现这一点?
由于您有排列,您可以确定每行都会过滤掉相同数量的项目。因此,您可以安全地矢量应用掩码,并将 1D 中间值
reshape
应用于原始行数:
mask = X != k
X[mask].reshape(X.shape[0], -1)
输出:
array([[4, 3, 5, 2],
[5, 3, 2, 4],
[3, 2, 4, 5],
[2, 4, 3, 5],
[3, 5, 2, 4]])
1M 行的时序:
103 ms ± 8.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)