我有一个矩阵,它表示到一组点的k近邻的距离,
并且有一个最近邻的类标签矩阵。(N-by-k矩阵)
如果没有显式的python循环(实际上,我想在那些循环不起作用的地方实现这一点)来构建一个(N-by-classes)矩阵,它的(I,j)元素是从I-th点到它的k-NN点的距离之和,并且类标签为“j”,那么最好的方法是什么?
例子:
# N = 2
# k = 5
# number of classes = 3
K_val = np.array([[1,2,3,4,6],
[2,4,5,5,7]])
l_val = np.array([[0,1,2,0,1],
[2,0,1,2,0]])
"""
result -> [[5,8,3],
[11,5,7]]
"""
最佳答案
你可以用
numpy.bincount。它
有一个weights
参数,允许您计算l_val
中的项目
但要根据K_val
来衡量物品的重量。
唯一的小问题是K_val
和l_val
的每一行似乎都是独立处理的。因此,将shift添加到l_val
中,这样每一行都有不同于其他行的值。
import numpy as np
num_classes = 3
K_val = np.array([[1,2,3,4,6],
[2,4,5,5,7]])
l_val = np.array([[0,1,2,0,1],
[2,0,1,2,0]])
def label_distance(l_val, K_val):
nrows, ncols = l_val.shape
shift = (np.arange(nrows)*num_classes)[:, np.newaxis]
result = (np.bincount((l_val+shift).ravel(), weights=K_val.ravel(),
minlength=num_classes*nrows)
.reshape(nrows, num_classes))
return result
print(label_distance(l_val, K_val))
产量
[[ 5. 8. 3.]
[ 11. 5. 7.]]
虽然senderle的方法非常优雅,但使用bincount更快:
def using_extradim(l_val, K_val):
return (K_val[:,:,None] * (l_val[:,:,None] == numpy.arange(3)[None,None,:])).sum(axis=1)
In [34]: K2 = np.tile(K_val, (1000,1))
In [35]: L2 = np.tile(l_val, (1000,1))
In [36]: %timeit using_extradim(L2, K2)
1000 loops, best of 3: 584 µs per loop
In [40]: %timeit label_distance(L2, K2)
10000 loops, best of 3: 67.7 µs per loop