目前我正试图对一个包含单元素的列表进行热编码。有什么干净的Pythonic方法可以从表示方式2转到表示方式1?此外,我还想知道从表示1到表示2的简洁方法。
表示法1
[[1. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0. 0.]
...
[0. 0. 1. 0. 0. 0.]
[0. 0. 0. 1. 0. 0.]
[0. 0. 1. 0. 0. 0.]]
(256, 6)
表述2
[[0.]
[3.]
[3.]
...
[2.]
[3.]
[2.]]
(256, 1)
使用纯粹的基本条件列表理解,对于表示方式1到2。
r1 = [[1., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 1., 0.]]
len_r1l = len(r1[0]) # length of each sublist, here 6
r2 = [[0], [3], [4]]
r1_r2 = [[i] for l in r1 for i in range(len_r1l) if l[i]==1]
>>> [[0], [3], [4]]
和表征2到1:
r2_r1 = [[1. if i==idx[0] else 0 for i in range(len_r1l)] for idx in r2]
>>> [[1.0, 0, 0, 0, 0, 0],
[0, 0, 0, 1.0, 0, 0],
[0, 0, 0, 0, 1.0, 0]]
等价地使用numpy,与... np.非零:
# convert to array
r1_np = np.asarray(r1)
r2_np = np.asarray(r2)
r1_r2 = np.nonzero(r1_np)[1]
>>> array([0, 3, 4])
r2_r1 = np.zeros_like(r1_np)
r2_r1[np.arange(r1_r2.shape[0]),r1_r2] = 1.
>>> array([[1., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 1., 0.]])
如果你真的想保持它 list
使用 np.ndarray.tolist。 方法。
r1_r2.tolist()
>>> [0, 3, 4]
r2_r1.tolist()
>>> [[1.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, 1.0, 0.0]]
以这些答案为基准,打算投入的规模。256
清楚地显示了numpy的效率。
# representation 1 to 2
%timeit [[i] for l in r1 for i in range(len_r1l) if l[i]==1]
>>> 199 µs ± 431 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit np.nonzero(r1_np)[1]
>>> 13 µs ± 32.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# representation 2 to 1
%timeit [[1. if i==idx[0] else 0 for i in range(len_r1l)] for idx in r2]
>>> 243 µs ± 820 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit r2_r1 = np.zeros_like(r1_np); r2_r1[np.arange(r1_r2.shape[0]),r1_r2] = 1.
>>> 9.42 µs ± 15.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
希望这对你有帮助
表示方式1--> 2:
如果你知道每一个列表都有一个且只有一个。1
,您可以使用 list.index
在...中 名单理解:
list_of_lists = [ # Your initial list
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
]
list_of_ones_indices = [[lst.index(1)] for lst in list_of_lists]
# [0, 1, 2]
代表2-> 1:
该numpy解决方案 可能更接近你的需求。如果你想要一个纯Python的解决方案,你可以这样做。
index_list = [1, 2, 3]
LENGTH = 6
one_hot_list = []
# This can also be achieved with a list comprehension and range()
for index in index_list:
one_hot = [0] * LENGTH
one_hot[index[0]] = 1
one_hot_list.append(one_hot)
print(one_hot_list)
# [
# [0, 1, 0, 0, 0, 0],
# [0, 0, 1, 0, 0, 0],
# [0, 0, 0, 1, 0, 0]
# ]
为了将表示方式2转换为表示方式1,你可以使用类似于... keras.np_utils.to_categorical
:
>>> y = [0, 1, 2]
>>> np_utils.to_categorical(y)
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
:国际联合检查组。
np.argmax(a, axis=1)[:, None]
使用@Yacola设置。
r1 = [[1., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.],
[0., 0., 0., 0., 1., 0.]]
a = np.array(r1)
np.argmax(a, axis=1)[:, None]
输出:
array([[0],
[3],
[4]])
使用numpy,
rep_2 = np.where(condition)[1].reshape(rep1.shape[0], 1)
哪儿 condition
可以用很多方式来说明,其中有。
根据你的要求。如果你愿意,可以将rep_2转换为一个列表。