给定这些数组,
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]
条目。你需要决定这个结果是否符合你的需要。