为什么类别列在 pandas 中被视为字符串列?

Why is a category column seen as a column of strings in pandas?

我有一个包含整数、浮点数和字符串的数据集。我(认为我)通过以下语句将所有字符串转换为类别:

for col in list (X):
    if X[col].dtype == np.object_:#dtype ('object'):
        X [col] = X [col].str.lower().astype('category', copy=False)

但是,当我想为随机森林模型输入数据时,出现错误:

ValueError: could not convert string to float: 'non-compliant by no payment'

字符串 'non-compliant by no payment' 出现在名为 X['compliance_detail'] 的列中,当我请求它的 dtype 时,我得到 category。当我询问它的值时:

In[111]: X['compliance_detail'].dtype
Out[111]: category
In[112]: X['compliance_detail'].value_counts()
Out[112]: 
non-compliant by no payment                        5274
non-compliant by late payment more than 1 month     939
compliant by late payment within 1 month            554
compliant by on-time payment                        374
compliant by early payment                           10
compliant by payment with no scheduled hearing        7
compliant by payment on unknown date                  3
Name: compliance_detail, dtype: int64

有人知道这里发生了什么吗?为什么在分类数据中看到字符串?为什么为此列列出 Int64 的数据类型?

感谢您的宝贵时间。

当您转换为类别类型时,该列保留其原始 repr,但 pandas 会跟踪类别。

s

0    foo
1    bar
2    foo
3    bar
4    foo
5    bar
6    foo
7    foo
Name: A, dtype: object

s = s.astype('category')
s

0    foo
1    bar
2    foo
3    bar
4    foo
5    bar
6    foo
7    foo
Name: A, dtype: category
Categories (2, object): [bar, foo]

如果您想要整数类别,您有以下几种选择:

选项 1
cat.codes

s.cat.codes
0    1
1    0
2    1
3    0
4    1
5    0
6    1
7    1
dtype: int8

选项 2
pd.factorizeastype 不需要)

pd.factorize(s)[0]
array([0, 1, 0, 1, 0, 1, 0, 0])

我应该更仔细地阅读文档 ;-) sklearn 中的大多数统计测试不处理类别,就像它们在 R 中那样。RandomForestClassifiers 理论上可以毫无问题地处理类别,sklearn 中的实现不允许它(目前)。我的错误是认为他们可以这样做,因为理论上说他们可以并且它在 R 中运行良好。但是,the sklearn documentation 对拟合函数说了以下内容:

X : array-like or sparse matrix of shape = [n_samples, n_features]

The training input samples. Internally, its dtype will be converted to dtype=np.float32. If a sparse matrix is provided, it will be converted into a sparse csc_matrix.

因此没有类别的空间,当它们被分解时,它们被视为数字。 In this article 解释了类别在 Pandas 中的工作原理以及它们的陷阱是什么。我建议所有想使用类别的人阅读它,尤其是具有 R 背景的人。我希望这方面能得到改善,因为在目前的情况下有些程序不能充分利用。