使用NumPy沿任意维度一键编码

时间:2019-04-23 20:54:06

标签: python numpy one-hot-encoding

给出一个具有任意多个维度的numpy数组,我希望能够对其中任何一个维度进行一次热编码。例如,假设我有一个形状为a的数组(10, 20, 30, 40),我可能想对第二维进行热编码,即变换a,使结果仅包含值0 1a[i, :, j, k]分别为ijk的每个选择均包含一个零条目(在该维度上先前最大值的位置) )。

我考虑过先获取a.argmax(axis=1),然后使用np.ogrid将其转换为指向最大值的索引,但我无法弄清楚细节。我也担心这种方法会消耗内存。

是否有一种简单的方法(理想情况下只需要很少的额外内存)?

1 个答案:

答案 0 :(得分:3)

这是array-assignment的一种方式-

def onehotencode_along_axis(a, axis):
    # Setup o/p hot encoded bool array 
    h = np.zeros(a.shape,dtype=bool)
    idx = a.argmax(axis=axis)

    # Setup same dimensional indexing array as the input
    idx = np.expand_dims(idx, axis) # Thanks to @Peter

    # Finally assign True values
    np.put_along_axis(h,idx,1,axis=axis)
    return h

示例在2D情况下运行-

In [109]: np.random.seed(0)
     ...: a = np.random.randint(11,99,(4,5))

In [110]: a
Out[110]: 
array([[55, 58, 75, 78, 78],
       [20, 94, 32, 47, 98],
       [81, 23, 69, 76, 50],
       [98, 57, 92, 48, 36]])

In [112]: onehotencode_along_axis(a, axis=0)
Out[112]: 
array([[False, False, False,  True, False],
       [False,  True, False, False,  True],
       [False, False, False, False, False],
       [ True, False,  True, False, False]])

In [113]: onehotencode_along_axis(a, axis=1)
Out[113]: 
array([[False, False, False,  True, False],
       [False, False, False, False,  True],
       [ True, False, False, False, False],
       [ True, False, False, False, False]])

针对更高(多维)的5D案例进行验证的示例运行-

In [114]: np.random.seed(0)
     ...: a = np.random.randint(11,99,(2,3,4,5,6))
     ...: for i in range(a.ndim):
     ...:     out = onehotencode_along_axis(a, axis=i)
     ...:     print np.allclose(out.sum(axis=i),1)
True
True
True
True
True

如果您需要最终输出为包含int0的{​​{1}}数组,请在布尔输出数组上使用一个视图:

1等。