[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)
但它没有起作用。
有没有一种方法可以在一行中实现这个?
[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)
但它没有起作用。
有没有一种方法可以在一行中实现这个?
通常,在机器学习中想要获得分类的一位有效编码时,您会有一个索引数组。
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)
np.eye(nb_classes)
应该是6x6矩阵,但它的形状变成了4x6。你能详细说明一下吗? - mrgloomnp.eye(nb_classes)
是一个 6x6 的矩阵。然后我选择目标中指定的行。我只选择了四行,所以它是一个 4x6 的矩阵。 - Martin Thoma.reshape(list(targets.shape)+[nb_classes])
来推广到更多形状。 - siddhadevnp.eye(nb_classes)[np.array(targets).reshape(-1)]
能够工作吗?它是一个由 H*W 矩阵索引的 CxC 矩阵?!这里到底发生了什么? - gebbissimonp.eye(n)
的用途。然后看看 np.eye(5)[[3, 1]]
是什么意思。 - Martin Thoma类似于:
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()
之前定义数组
numpy.zeros
可能甚至比C for
循环运行得更快,因为CPU可以非常快地用单个值填充一块内存。 - PM 2Ring[0 if i !=5 else 1 for i in range(10)]
[0,0,0,0,0,1,0,0,0,0]
我不确定性能如何,但以下代码可以正常工作,而且很整洁。
x = np.array([0, 5])
x_onehot = np.identity(6)[x]
使用 np.identity
或 np.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.]]
tf.one_hot
函数:https://www.tensorflow.org/api_docs/python/array_ops/slicing_and_joining#one_hot。问题在于你没有将数组保存在任何地方。 put
函数直接在数组上进行操作并不返回任何值。由于你从未给数组命名,因此以后无法引用它。因此,这段代码:
one_pos = 5
x = np.zeros(10)
np.put(x, one_pos, 1)
使用 would work 也可以,但你也可以使用索引:
one_pos = 5
x = np.zeros(10)
x[one_pos] = 1
在我看来,如果没有特殊的原因要求成为一行代码,则这是正确的做法。这也更容易阅读,易读的代码是好的代码。
np.put
没有返回值。虽然您的技术很好,但是您访问的是None
而不是结果数组。arr = np.zeros(10)
np.put(arr, 5, 1)
put
的方法:arr[5] = 1
np.put
会对其数组参数进行原地变异。在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]
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 ---
a=np.zeros(10)
,我得到了第一个版本稍微快一点的结果:第一个版本为 0.0007712841033935547 秒
,而第二个版本为 0.0008835792541503906 秒
。 - HolyDannaa = np.zeros(10); a[l] = 1
进行索引赋值,比调用函数更快。我的one_hot
函数比这个内联版本稍慢,也是由于函数调用的开销,但它比其他技术更快。然而,这个时间信息并不是非常准确的,你应该使用timeit
模块,并使用它的设施进行数百(或数千)次测试,以获得有意义的结果,这些结果不会被CPU执行的其他任务的“噪音”所淹没。 - PM 2Ring