繁体   English   中英

将一个热行向量的numpy数组转换为索引的列向量

[英]Turn a numpy array of one hot row vectors into a column vector of indices

那么什么是转换numpy数组的简洁有效的方法,如:

[[0, 0, 1],
[1, 0, 0],
[0, 1, 0]]

进入如下列:

[[2],
 [0],
 [1]]

其中每列中的数字是一个热矢量的原始数组中“1”的索引值?

我正在考虑循环遍历行并创建索引值为1的列表,但我想知道是否有更有效的方法来执行它。 谢谢你的任何建议。

更新 :有关更快的解决方案,请参阅Divakar的回答。


您可以使用numpy数组的nonzero nonzero()方法 它返回的元组的第二个元素是你想要的。 例如,

In [56]: x
Out[56]: 
array([[0, 0, 1, 0],
       [0, 0, 1, 0],
       [0, 0, 0, 1],
       [0, 0, 0, 1],
       [1, 0, 0, 0]])

In [57]: x.nonzero()[1]
Out[57]: array([2, 2, 3, 3, 0])

根据numpy.nonzero()docstring ,“ a中的值总是以行主,C风格的顺序进行测试和返回”,所以只要每行中只有一个1, x.nonzero()[1]将从第一行开始给出每行1的位置。 (而x.nonzero()[0]将等于range(x.shape[0]) 。)

要将结果作为具有shape(n,1)的数组,可以使用reshape()方法

In [59]: x.nonzero()[1].reshape(-1, 1)
Out[59]: 
array([[2],
       [2],
       [3],
       [3],
       [0]])

或者您可以使用[:, np.newaxis]进行索引:

In [60]: x.nonzero()[1][:, np.newaxis]
Out[60]: 
array([[2],
       [2],
       [3],
       [3],
       [0]])

我们正在使用热编码阵列,确保每行一个1 因此,如果我们只是寻找每行的第一个非零索引,我们将得到所需的结果。 因此,我们可以沿着每一行使用np.argmax ,就像这样 -

a.argmax(axis=1)

如果你想要一个2D数组作为o / p,只需在最后添加一个单一维度 -

a.argmax(axis=1)[:,None]

运行时测试 -

In [20]: # Let's create a sample hot encoded array
    ...: a = np.zeros((1000,1000),dtype=int)
    ...: idx = np.random.randint(0,1000,1000)
    ...: a[np.arange(1000),idx] = 1
    ...: 

In [21]: %timeit a.nonzero()[1] # @Warren Weckesser's soln
100 loops, best of 3: 9.03 ms per loop

In [22]: %timeit a.argmax(axis=1)
1000 loops, best of 3: 1.15 ms per loop

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM