50

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

[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)

但它没有用。

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

4

9 回答 9

105

通常,当您想要在机器学习中获得用于分类的 one-hot 编码时,您有一个索引数组。

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是一个特殊的值,意思是“把所有剩余的东西都放在这个维度上”。由于只有一个,它会使阵列变平。

复制粘贴解决方案

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)
于 2017-03-18T13:01:10.983 回答
10

就像是 :

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()

于 2016-07-26T14:19:15.380 回答
5

您可以使用列表理解:

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

转向

[0,0,0,0,0,1,0,0,0,0]
于 2017-11-17T14:49:05.503 回答
3

使用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

于 2017-02-07T05:24:05.333 回答
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

在我看来,如果没有特殊原因将其作为一个班轮这样做,那将是正确的方法。这也可能更容易阅读并且可读的代码是好的代码。

于 2016-07-26T14:27:29.397 回答
2

快速查看手册,您会发现np.put它没有返回值。虽然您的技术很好,但您正在访问None而不是结果数组。

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

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

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

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

arr[5] = 1
于 2016-07-26T14:27:48.443 回答
2

就地改变其np.put数组 arg 。在 Python 中,执行就地突变以返回的函数/方法是常规的;遵守该公约。所以如果是一维数组,你做Nonenp.puta

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]
于 2016-07-26T14:47:10.097 回答
2

我不确定性能,但以下代码有效并且很整洁。

x = np.array([0, 5])
x_onehot = np.identity(6)[x]
于 2017-06-05T03:45:09.653 回答
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 ---
于 2016-07-26T15:02:40.710 回答