numpy将分类字符串数组转换为整数数组

wro*_*coe 14 python statistics numpy machine-learning

我正在尝试将分类变量的字符串数组转换为分类变量的整数数组.

防爆.

import numpy as np
a = np.array( ['a', 'b', 'c', 'a', 'b', 'c'])
print a.dtype
>>> |S1

b = np.unique(a)
print b
>>>  ['a' 'b' 'c']

c = a.desired_function(b)
print c, c.dtype
>>> [1,2,3,1,2,3] int32
Run Code Online (Sandbox Code Playgroud)

我意识到这可以通过循环完成,但我想有一种更简单的方法.谢谢.

Jos*_*sef 39

np.unique有一些可选的返回

return_inverse给出了我经常使用的整数编码

>>> b, c = np.unique(a, return_inverse=True)
>>> b
array(['a', 'b', 'c'], 
      dtype='|S1')
>>> c
array([0, 1, 2, 0, 1, 2])
>>> c+1
array([1, 2, 3, 1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

它可以用于从唯一身份重新创建原始数组

>>> b[c]
array(['a', 'b', 'c', 'a', 'b', 'c'], 
      dtype='|S1')
>>> (b[c] == a).all()
True
Run Code Online (Sandbox Code Playgroud)


ben*_*oss 27

... 多年后....

为了完整(因为这不是在答案中提到)和(我个人的原因一直pandas在我的模块中引入的,但不一定sklearn),这也与相当简单pandas.get_dummies()

import numpy as np
import pandas

In [1]: a = np.array(['a', 'b', 'c', 'a', 'b', 'c'])

In [2]: b = pandas.get_dummies(a)

In [3]: b
Out[3]: 
      a  b  c
   0  1  0  0
   1  0  1  0
   2  0  0  1
   3  1  0  0
   4  0  1  0
   5  0  0  1

In [3]: b.values.argmax(1)
Out[4]: array([0, 1, 2, 0, 1, 2])
Run Code Online (Sandbox Code Playgroud)


ars*_*ars 18

一种方法是使用scikits.statsmodels中categorical函数.例如:

In [60]: from scikits.statsmodels.tools import categorical

In [61]: a = np.array( ['a', 'b', 'c', 'a', 'b', 'c'])

In [62]: b = categorical(a, drop=True)

In [63]: b.argmax(1)
Out[63]: array([0, 1, 2, 0, 1, 2])
Run Code Online (Sandbox Code Playgroud)

categorical(b)的返回值实际上是一个设计矩阵,因此调用argmax上面的方法使其接近您想要的格式.

In [64]: b
Out[64]:
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
Run Code Online (Sandbox Code Playgroud)


Gre*_*urm 5

另一种选择是使用分类熊猫系列:

>>> import pandas as pd
>>> pd.Series(['a', 'b', 'c', 'a', 'b', 'c'], dtype="category").cat.codes.values

array([0, 1, 2, 0, 1, 2], dtype=int8)
Run Code Online (Sandbox Code Playgroud)


Tim*_*sen 5

另一种方法是使用sklearn.preprocessing.LabelEncoder

它可以将可散列标签(如字符串)转换为 0 到 之间的数值n_classes-1

它是这样完成的:

# Repeating setup from the question to make example copy/paste-able
import numpy as np
a = np.array( ['a', 'b', 'c', 'a', 'b', 'c'])
b = np.unique(a)

# Answer to the question
from sklearn import preprocessing
pre = preprocessing.LabelEncoder()
pre.fit(b)
c = pre.transform(a)

print(c)    # Prints [0 1 2 0 1 2]
Run Code Online (Sandbox Code Playgroud)

如果您坚持让结果数组中的值从 1 开始,您可以简单地c + 1稍后执行。

仅为了执行此操作而将 sklearn 作为项目的依赖项引入可能不值得,但如果您已经导入了 sklearn,那么这是一个不错的选择。


unu*_*tbu 1

嗯,这是一个黑客......但它有帮助吗?

In [72]: c=(a.view(np.ubyte)-96).astype('int32')

In [73]: print(c,c.dtype)
(array([1, 2, 3, 1, 2, 3]), dtype('int32'))
Run Code Online (Sandbox Code Playgroud)

  • 您真的想添加一个警告,即这只适用于长度为 1 的字符串。 (19认同)