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

时间:2017-10-01 19:45:50

标签: python pandas dataframe categories

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

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'

字符串'不符合付款条件'发生在名为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

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

感谢您的时间。

2 个答案:

答案 0 :(得分:1)

转换为类别类型时,列保留在其原始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.factorize astype不需要)

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

答案 1 :(得分:1)

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

  

X:形状的数组或稀疏矩阵= [n_samples,n_features]

     

培训输入样本。在内部,其dtype将转换为dtype = np.float32。如果提供稀疏矩阵,则将其转换为稀疏csc_matrix。

因此没有类别的空间,当它们被分解时,它们被视为数字。 In this article解释了类别如何在熊猫中发挥作用以及它们的缺陷是什么。我建议所有想要使用类别的人阅读它,特别是在有R背景时。我希望这方面会有所改善,因为目前的情况是无法充分利用某些程序。