尝试使用OneHotEncoder结果创建数据框时出现ValueError

时间:2020-06-18 13:30:23

标签: python machine-learning scikit-learn

我最近开始学习python,以使用机器学习方法为研究项目开发预测模型。我已经使用OneHotEncoder对数据集中的所有类别变量进行了编码

    # Encode categorical data with oneHotEncoder
    from sklearn.preprocessing import OneHotEncoder
    ohe = OneHotEncoder(handle_unknown='ignore')
    Z = ohe.fit_transform(Z)

我现在想用OneHotEncoder的结果创建一个数据框。我希望dataframe列成为编码产生的新类别,这就是为什么我使用 categories _ 属性。运行以下代码行时:

    ohe_df = pd.DataFrame(Z, columns=ohe.categories_)

我收到错误: ValueError:所有数组的长度必须相同

我知道错误消息中引用的数组是类别的数组,每个类别具有不同的长度,具体取决于其包含的类别数量,但是我不确定用什么方法创建数据框的正确方法列为新类别时(具有多个功能时)。

我试图用一个仅包含一个功能的小型数据集来做到这一点,并且有效:

    ohe = OneHotEncoder(handle_unknown='ignore', sparse=False)
    df = pd.DataFrame(['Male', 'Female', 'Female'])
    results = ohe.fit_transform(df)

    ohe_df = pd.DataFrame(results, columns=ohe.categories_)
    ohe_df.head()
    
        Female  Male
    0   0.0     1.0
    1   1.0     0.0
    2   1.0     0.0

那么我如何对具有众多功能的大型数据集执行相同的操作。

谢谢。

编辑:

根据要求,我想出了一个MWE来演示它是如何工作的:


    import numpy as np
    import pandas as pd
    
    # create dataframe 
    df = pd.DataFrame(np.array([['Male', 'Yes', 'Forceps'], ['Female', 'No', 'Forceps and ventouse'],
                                 ['Female','missing','None'], ['Male','Yes','Ventouse']]), 
                      columns=['gender', 'diabetes', 'assistance'])
    
    df.head()
    
    # encode categorical data 
    from sklearn.preprocessing import OneHotEncoder
    
    ohe = OneHotEncoder(handle_unknown='ignore')
    results = ohe.fit_transform(df)
    print(results)

通过这一步,我创建了一个分类数据的数据框并对其进行了编码。现在,我想创建另一个数据框,以使新数据框的列是由OneHotEncoder创建的类别,行是编码的数据。为此,我尝试了两件事:

    ohe_df = pd.DataFrame(results, columns=np.concatenate(ohe.categories_))

我尝试:

    ohe_df = pd.DataFrame(results, columns=ohe.get_feature_names(input_features=df.columns))

两者均导致错误: ValueError:传递的值的形状为(4,1),索引表示为(4,9)

2 个答案:

答案 0 :(得分:3)

ohe.categories_是一个数组列表,每个功能一个数组。您需要将其展平为pd.DataFrame的一维列表/数组,例如与np.concatenate(ohe.categories_)

但可能更好,请使用内置方法get_feature_names

答案 1 :(得分:3)

IIUC,

import numpy as np
import pandas as pd

# create dataframe 
df = pd.DataFrame(np.array([['Male', 'Yes', 'Forceps'], ['Female', 'No', 'Forceps and ventouse'],
                            ['Female','missing','None'], ['Male','Yes','Ventouse']]), 
                    columns=['gender', 'diabetes', 'assistance'])

df.head()

# encode categorical data 
from sklearn.preprocessing import OneHotEncoder

ohe = OneHotEncoder(handle_unknown='ignore')
results = ohe.fit_transform(df)
df_results = pd.DataFrame.sparse.from_spmatrix(results)
df_results.columns = ohe.get_feature_names(df.columns)
df_results

输出:

   gender_Female  gender_Male  diabetes_No  diabetes_Yes  diabetes_missing  assistance_Forceps  assistance_Forceps and ventouse  assistance_None  assistance_Ventouse
0            0.0          1.0          0.0           1.0               0.0                 1.0                              0.0              0.0                  0.0
1            1.0          0.0          1.0           0.0               0.0                 0.0                              1.0              0.0                  0.0
2            1.0          0.0          0.0           0.0               1.0                 0.0                              0.0              1.0                  0.0
3            0.0          1.0          0.0           1.0               0.0                 0.0                              0.0              0.0                  1.0

请注意,ohe.fit_transform(df)的输出是一个稀疏矩阵。

print(type(results))
<class 'scipy.sparse.csr.csr_matrix'>

您可以使用pd.DataFrame.sparse.from_spmatrix将其转换为数据框。然后,我们可以使用ohe.get_feature_names并将原始数据框列传递给结果数据框df_results中的列。