如何使用Numpy对字符串数组进行one-hot编码?

5
我知道有次优解决方案,但我正在尝试优化我的代码。到目前为止,我找到的最短的方法是这样的:
import numpy as np
from sklearn.preprocessing import OrdinalEncoder

target = np.array(['dog', 'dog', 'cat', 'cat', 'cat', 'dog', 'dog', 'cat', 'cat'])

oe = OrdinalEncoder()
target = oe.fit_transform(target.reshape(-1, 1)).ravel()
target = np.eye(np.unique(target).shape[0])[np.array(target, dtype=np.int32)]
print(target)

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

这是一段冗长且难看的代码,删除任何部分都将导致其无法正常工作。我正在寻找一种更简单的方法,不需要调用两个不同库中超过六个函数。


oe 生成的 target 是什么? - hpaulj
3个回答

5

明白了。这将适用于包含任意数量独特值的数组。

import numpy as np

target = np.array(['dog', 'dog', 'cat', 'cat', 'cat', 'dog', 'dog', 
    'cat', 'cat', 'hamster', 'hamster'])

def one_hot(array):
    unique, inverse = np.unique(array, return_inverse=True)
    onehot = np.eye(unique.shape[0])[inverse]
    return onehot

print(one_hot(target))

Out[9]: [[0.,1.,0.], [0.,1.,0.], [1.,0.,0.], [1.,0.,0.], [1.,0.,0.], [0.,1.,0.], [0.,1.,0.], [1.,0.,0.], [1.,0.,0.], [0.,0.,1.], [0.,0.,1.]]
这是一个由 11 行 3 列的矩阵组成的列表。每行表示一个长度为 3 的向量。所有数字都是浮点数,用于表示数据。

preprocessing.OneHotEncoder 也可以做到这一点,但是你的方法更快。 - hpaulj
你为什么没有使用numpy.uniquereturn_inverse参数,而是使用了numpy.searchsorted?另外,在np.array(array)中,你正在对已经是数组的东西调用numpy.array - user2357112
另外,使用 return_counts=True 是不必要的。你只是用结果的长度,但那个长度和 words 的长度是一样的。 - user2357112

1

为什么不使用 OneHotEncoder

>>> from sklearn.preprocessing import OneHotEncoder
>>> ohe = OneHotEncoder(categories='auto', sparse=False)
>>> arr = ohe.fit_transform(target[:, np.newaxis])
>>> arr
array([[0., 1.],
       [0., 1.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [0., 1.],
       [0., 1.],
       [1., 0.],
       [1., 0.]])

它保存了有关转换的良好元数据:
>>> ohe.categories_
[array(['cat', 'dog'], dtype='<U3')]

另外,您可以轻松地进行转换:

>>> ohe.inverse_transform(arr).ravel()
array(['dog', 'dog', 'cat', 'cat', 'cat', 'dog', 'dog', 'cat', 'cat'],
      dtype='<U3')

0

你可以使用Keras和LabelEncoder来实现它

import numpy as np
from keras.utils import to_categorical
from sklearn.preprocessing import LabelEncoder

# define example
data = np.array(['dog', 'dog', 'cat', 'cat', 'cat', 'dog', 'dog', 'cat', 'cat'])

label_encoder = LabelEncoder()
data = label_encoder.fit_transform(data)
# one hot encode
encoded = to_categorical(data)

这不是NumPy。 - Nicolas Gervais

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接