为什么类别列在 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.factorize
(astype
不需要)
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 背景的人。我希望这方面能得到改善,因为在目前的情况下有些程序不能充分利用。
我有一个包含整数、浮点数和字符串的数据集。我(认为我)通过以下语句将所有字符串转换为类别:
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.factorize
(astype
不需要)
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 背景的人。我希望这方面能得到改善,因为在目前的情况下有些程序不能充分利用。