一个使用numpy的热编码

时间:2016-07-26 14:15:02

标签: python numpy one-hot-encoding

如果输入为零,我想创建一个如下所示的数组:

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

如果输入为5:

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

对于上面我写道:

np.put(np.zeros(10),5,1)

但它不起作用。

有没有什么方法可以在一行中实现?

9 个答案:

答案 0 :(得分:51)

通常,当你想在机器学习中获得一个热门编码进行分类时,就会有一系列索引。

import numpy as np
nb_classes = 6
targets = np.array([[2, 3, 4, 0]]).reshape(-1)
one_hot_targets = np.eye(nb_classes)[targets]

one_hot_targets现在是

array([[[ 0.,  0.,  1.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  1.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  1.,  0.],
        [ 1.,  0.,  0.,  0.,  0.,  0.]]])

.reshape(-1)用于确保您拥有正确的标签格式(您可能还有[[2], [3], [4], [0]])。 -1是一个特殊值,表示"将所有剩余的内容放在此维度中#34;。由于只有一个,它会使阵列变平。

复制粘贴解决方案

def get_one_hot(targets, nb_classes):
    res = np.eye(nb_classes)[np.array(targets).reshape(-1)]
    return res.reshape(list(targets.shape)+[nb_classes])

封装

您可以使用mpu.ml.indices2one_hot。它经过测试且易于使用:

import mpu.ml
one_hot = mpu.ml.indices2one_hot([1, 3, 0], nb_classes=5)

答案 1 :(得分:9)

类似的东西:

np.array([int(i == 5) for i in range(10)])

应该做的伎俩。 但我想存在使用numpy的其他解决方案。

编辑:你的公式不起作用的原因:np.put不返回任何内容,它只是修改第一个参数中给出的元素。使用np.put()时的好答案是:

a = np.zeros(10)
np.put(a,5,1)

问题在于它无法在一行中完成,因为您需要先定义数组,然后再将其传递给np.put()

答案 2 :(得分:3)

您可以使用列表理解:

[0 if i !=5 else 1 for i in range(10)]

转向

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

答案 3 :(得分:2)

这里的问题是您无法保存数组。 put函数在数组上就位,不返回任何内容。由于您永远不会为您的阵列命名,因此以后无法解决。所以这个

one_pos = 5
x = np.zeros(10)
np.put(x, one_pos, 1)

会起作用,但是你可以使用索引:

one_pos = 5
x = np.zeros(10)
x[one_pos] = 1

在我看来,如果没有特殊原因可以做到这一点,这将是正确的方法。这可能也更容易阅读,可读代码是很好的代码。

答案 4 :(得分:2)

快速查看the manual,您会看到np.put未返回值。虽然您的技术很好,但您正在访问None而不是结果数组。

对于一维数组,最好只使用直接索引,尤其是对于这样一个简单的情况。

以下是如何通过最少的修改来重写代码:

arr = np.zeros(10)
np.put(arr, 5, 1)

以下是如何使用索引编写第二行而不是put

arr[5] = 1

答案 5 :(得分:2)

np.put将其数组arg 就地变异。它在Python中是常规的,用于执行就地突变以返回None的函数/方法; np.put遵守该惯例。因此,如果a是一维数组,那么

a = np.put(a, 5, 1)

然后a将替换为None

您的代码与此类似,但它将未命名的数组传递给np.put

紧凑型&有效的方式来做你想要的是一个简单的功能,例如:

import numpy as np

def one_hot(i):
    a = np.zeros(10, 'uint8')
    a[i] = 1
    return a

a = one_hot(5) 
print(a)

<强>输出

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

答案 6 :(得分:2)

使用np.identitynp.eye。您可以使用输入i和数组大小s尝试类似的内容:

np.identity(s)[i:i+1]

例如,print(np.identity(5)[0:1])将导致:

[[ 1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]]

如果您使用的是TensorFlow,则可以使用tf.one_hothttps://www.tensorflow.org/api_docs/python/array_ops/slicing_and_joining#one_hot

答案 7 :(得分:0)

import time
start_time = time.time()
z=[]
for l in [1,2,3,4,5,6,1,2,3,4,4,6,]:
    a= np.repeat(0,10)
    np.put(a,l,1)
    z.append(a)
print("--- %s seconds ---" % (time.time() - start_time))

#--- 0.00174784660339 seconds ---

import time
start_time = time.time()
z=[]
for l in [1,2,3,4,5,6,1,2,3,4,4,6,]:
    z.append(np.array([int(i == l) for i in range(10)]))
print("--- %s seconds ---" % (time.time() - start_time))

#--- 0.000400066375732 seconds ---

答案 8 :(得分:0)

我不确定效果,但以下代码有效并且很简洁。

x = np.array([0, 5])
x_onehot = np.identity(6)[x]