我有一个序列s = [4,3,1,0,5],num_classes = 6并且我想生成一个m形状为Numpy的矩阵,(len(s), num_classes)其中m[i,j] = 1 if s[i] == j else 0。
s = [4,3,1,0,5]
num_classes = 6
m
(len(s), num_classes)
m[i,j] = 1 if s[i] == j else 0
Numpy中有这样的功能,我可以在其中传递s和num_classes?
s
num_classes
这也称为k的1编码或一热编码。
timeit 结果:
timeit
def b(): m = np.zeros((len(s), num_classes)) m[np.arange(len(s)), s] = 1 return m In [57]: timeit.timeit(lambda: b(), number=1000) Out[57]: 0.012787103652954102 In [61]: timeit.timeit(lambda: (np.array(s)[:,None]==np.arange(num_classes))+0, number=1000) Out[61]: 0.018411874771118164
由于您希望1每行一个,因此可以arange(len(s))沿第一个轴使用索引,而s沿第二个轴使用:
1
arange(len(s))
s = [4,3,1,0,5] n = len(s) k = 6 m = np.zeros((n, k)) m[np.arange(n), s] = 1 m => array([[ 0., 0., 0., 0., 1., 0.], [ 0., 0., 0., 1., 0., 0.], [ 0., 1., 0., 0., 0., 0.], [ 1., 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0., 1.]]) m.nonzero() => (array([0, 1, 2, 3, 4]), array([4, 3, 1, 0, 5]))
可以认为这是使用索引(0,4),然后是(1,3),然后是(2,1),(3,0),(4,5)。