我正在尝试使用numpy优化的内置函数来生成温度计编码.如果给定长度为1,则温度计编码基本上产生n量.例如,在8长度中,3将被编码为:
1 1 1 0 0 0 0 0
使用numpy基于整数输入生成该向量基本上是切片并设置1.
stream[:num_ones] = 1
所以我的问题是给出一个向量作为输入,例如,生成矩阵输出的最佳方法是:
[2 3 4 1]
作为输入应该产生:
[[1 1 0 0 0 0 0 0],
[1 1 1 0 0 0 0 0],
[1 1 1 1 0 0 0 0],
[1 0 0 0 0 0 0 0]]
我当前的解决方案是迭代所需大小的零矩阵,并使用我上面写的切片方法将所需的元素数设置为1.我有更快的方法吗?
最佳答案 我之前从未听说过“温度计编码”,但是当你意识到它与单热编码如此相似时,很明显你可以使用位移操作来实现:
>>> a = np.array([2, 3, 4, 1], dtype=np.uint8)
>>> print(np.fliplr(np.unpackbits((1 << a) - 1).reshape(-1,8)))
[[1 1 0 0 0 0 0 0]
[1 1 1 0 0 0 0 0]
[1 1 1 1 0 0 0 0]
[1 0 0 0 0 0 0 0]]
编辑:您可以通过处理8个列块来将想法概括为任意大小的整数:
a = np.array([2, 13, 4, 0, 1, 17], dtype=np.uint8)
out = np.empty((len(a), 0), dtype=np.uint8)
while a.any():
block = np.fliplr(np.unpackbits((1 << a) - 1).reshape(-1,8))
out = np.concatenate([out, block], axis=1)
a = np.where(a<8, 0, a-8)
print(out)
[[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0]
[1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0]]