【问题标题】:Most efficient one-hot-encoder最高效的 one-hot-encoder
【发布时间】:2020-06-30 15:00:40
【问题描述】:

说,我有一个 Numpy 数组 target,如下所示:

target = np.array([1, 2, 3, 2, 3, 2, 3, 1, 1, 3])

我知道目标值的范围:即1-3。

现在,我想创建一个目标的热编码,其长度与目标相同。

为此,我使用了以下代码:

target_one_hot = np.zeros([len(target], 4)

for i in range(0, len(target)):
    target_one_hot[i, target[i]] = 1

target_one_hot = = np.delete(target_one_hot , 0, 1)

这行得通。但是,我怀疑通过省略 for 循环可以更有效地编写此操作。我该怎么做?

【问题讨论】:

    标签: python-3.x numpy for-loop one-hot-encoding


    【解决方案1】:

    方法#1

    创建一个掩码(用于内存+性能。效率),将1s/True分配给目标给定的索引(以1开头时偏移一个),最后使用视图转换为int数组 -

    mask = np.zeros((len(target), 3), dtype=bool)
    mask[np.arange(len(target)),target-1] = 1
    out = mask.view('i1')
    

    如果需要最终输出为浮点数,请在开始时使用float dtype 初始化mask,并跳过最终的int 转换。

    方法 #2

    另一个通过在identity-matrix 上使用偏移target 进行索引来进行散列 -

    np.eye(3, dtype=bool)[target-1].view('i1')
    

    方法#3

    直接用target散列-

    np.eye(4, k=-1, dtype=bool)[target,:-1].view('i1')
    

    大型数据集的时序 -

    In [46]: target = np.random.randint(1,4,1000000)
    
    In [47]: %%timeit
        ...: mask = np.zeros((len(target), 3), dtype=bool)
        ...: mask[np.arange(len(target)),target-1] = 1
    10.3 ms ± 48.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    In [48]: %timeit np.eye(3, dtype=bool)[target-1]
    14.3 ms ± 241 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    In [49]: %timeit np.eye(4, k=-1, dtype=bool)[target]
    13.1 ms ± 80.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    【讨论】:

      【解决方案2】:

      为此有一个OneHotEncoder

      from sklearn.preprocessing import OneHotEncoder
      
      a = OneHotEncoder().fit_transform(target.reshape(-1,1))
      

      您的 One-hot 矩阵将是一个稀疏矩阵,您可以通过以下方式获取 numpy 数组:

      a.toarray()
      

      另一方面,如果您已经知道范围:

      np.array(np.arange(1,4)[:,None]==target, dtype=np.int)
      # 4.23 ms ± 66.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      

      【讨论】:

        猜你喜欢
        • 2019-04-21
        • 2017-05-04
        • 2017-01-28
        • 2021-05-01
        • 1970-01-01
        • 2017-06-07
        • 2021-10-29
        • 2017-06-21
        • 2021-10-09
        相关资源
        最近更新 更多