Python 3.x 最有效的一个热编码器

Python 3.x 最有效的一个热编码器,python-3.x,numpy,for-loop,one-hot-encoding,Python 3.x,Numpy,For Loop,One Hot Encoding,比如说,我有一个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 tar

比如说,我有一个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循环可以更有效地编写此操作。我如何才能做到这一点?

方法#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

另一个是通过索引
标识矩阵
和偏移的
目标
-

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

直接使用
target
-

np.eye(3, dtype=bool)[target-1].view('i1')
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)
方法#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

另一个是通过索引
标识矩阵
和偏移的
目标
-

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

直接使用
target
-

np.eye(3, dtype=bool)[target-1].view('i1')
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)

有一个
onehotcoder
用于:

from sklearn.preprocessing import OneHotEncoder

a = OneHotEncoder().fit_transform(target.reshape(-1,1))
您的一个热矩阵将是稀疏矩阵,您可以通过以下方式获得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)

有一个
onehotcoder
用于:

from sklearn.preprocessing import OneHotEncoder

a = OneHotEncoder().fit_transform(target.reshape(-1,1))
您的一个热矩阵将是稀疏矩阵,您可以通过以下方式获得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)