获取不同长度的索引来切片多维numpy数组



给定这些数组,

R = np.array([[ 5.,  3.,  2.,  7.,  3.,  6.,  8.,  9., 10., 55.],
[ 5.,  4.,  2.,  7.,  3.,  6.,  8., 10., 10., 55.]])
F = np.array([[ 0.2 ,  0.4 ,  0.1 ,  0.3 ,  0.25,  0.25,  0.2 ,  0.1 ,  0.1 , 0.1 ],
[ 0.3 , -0.4 ,  0.1 ,  0.3 ,  0.25,  0.25,  0.4 , -0.4 ,  0.1 , 0.1 ]])
K = nparray([[2],
[1]])

我想对F的每一行进行排序,然后找到第一行的第一个K[0]索引和排序后的F的第二行的第一个K[1]索引。然后使用这些索引,我想给R的元素加1。

这是我的尝试,我能够得到索引:

indices = np.argsort(F)[np.tile(np.arange(F.shape[1]),(F.shape[0],1)) < K]
# indices =  np.array([7, 8, 7], dtype=int64)

但是我不确定如何在不使用for循环的情况下对下面的操作进行矢量化。

Rnew = R.copy()
Rnew[0,7] =R[0,7]+1
Rnew[0,8] =R[0,8]+1
Rnew[1,7] =R[1,7]+1
Rnew = np.array([[ 5.,  3.,  2.,  7.,  3.,  6.,  8., 10., 11., 55.],
[ 5.,  4.,  2.,  7.,  3.,  6.,  8., 11., 10., 55.]])

我想这应该行得通:

m = np.arange(F.shape[1]) < K
Rnew = R.copy()
Rnew[np.nonzero(m)[0], np.argsort(F)[m]] += 1

由于第一行使用广播,所以不需要np.tile()

请注意,结果可能存在歧义:由于F的每一行都有重复多次的值(例如第一行为0.1,第二行为-0.4),np.argsort()可能给出F元素的不同顺序,这取决于这些相等值的排序方式。这可能会改变矩阵R的哪些条目将被加1。例如,代码可以增加R[0, 2]R[0, 9]R[1, 1]项,而不是增加R[0, 7]R[0, 8]R[1, 7]。要获得明确的结果,可以指定np.argsort()必须使用稳定的排序算法,该算法将保留相等元素的相对顺序:

m = np.arange(F.shape[1]) < K
Rnew = R.copy()
Rnew[np.nonzero(m)[0], np.argsort(F, kind="stable")[m]] += 1

在这个特定的例子中,这将增加R[0, 2],R[0, 7]R[1, 1]条目。你需要决定这个结果是否符合你的需要。

最新更新