首页 > 解决方案 > 包含字符串的对象列在转换为分类数据类型后保留字符串类型(Pandas Categorical)

问题描述

在 Pandas 中,我试图将包含字符串值的数据类型对象的数据转换为分类数据类型。即使在转换和系统显示数据类型是分类之后,我仍然能够对其执行字符串函数并pd.api.types.is_string_dtype返回True. 因此,当我尝试为数据拟合机器学习模型时,它会出错。

输入:

df_tmp["UsageBand"] = df_tmp["UsageBand"].astype("category")
df_tmp["UsageBand"].dtypes,pd.api.types.is_string_dtype(df_tmp["UsageBand"])

输出:(CategoricalDtype(categories=['High', 'Low', 'Medium'], ordered=True), **True**)

尝试拟合模型时出现错误

ValueError                                Traceback (most recent call last)
<timed exec> in <module>

~\machinelearning\sample-project\bulldozer-project\env\lib\site-packages\sklearn\ensemble\_forest.py in fit(self, X, y, sample_weight)
    293         """
    294         # Validate or convert input data
--> 295         X = check_array(X, accept_sparse="csc", dtype=DTYPE)
    296         y = check_array(y, accept_sparse='csc', ensure_2d=False, dtype=None)
    297         if sample_weight is not None:

~\machinelearning\sample-project\bulldozer-project\env\lib\site-packages\sklearn\utils\validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, warn_on_dtype, estimator)
    529                     array = array.astype(dtype, casting="unsafe", copy=False)
    530                 else:
--> 531                     array = np.asarray(array, order=order, dtype=dtype)
    532             except ComplexWarning:
    533                 raise ValueError("Complex data not supported\n"

~\machinelearning\sample-project\bulldozer-project\env\lib\site-packages\numpy\core\_asarray.py in asarray(a, dtype, order)
     83 
     84     """
---> 85     return array(a, dtype, copy=False, order=order)
     86 
     87 

ValueError: could not convert string to float: 'Low'

标签: pandasscikit-learn

解决方案


我没有将所有分类内容转换为数字,而是只对导致问题的空数据进行了这种转换。

错误代码:

for cols in df_tmp.columns:
    if not pd.api.types.is_numeric_dtype(df_tmp[cols]) and df_tmp[cols].isnull().sum() >0:
        df_tmp[cols+"_is_missing"] = df_tmp[cols].isnull()
        df_tmp[cols] = pd.Categorical(df_tmp[cols]).codes + 1   

正确代码:

for labels,content in df_tmp.items():
    if not pd.api.types.is_numeric_dtype(content):
        df_tmp[labels+"is_missing"] = pd.isnull(content)
        df_tmp[labels] = pd.Categorical(content).codes + 1   

推荐阅读