我有一个矩阵,它表示到一组点的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_vall_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

08-24 21:39