【问题标题】:Transform sklearn dataframe into Pandas dataframe, preserving categorical labels将 sklearn 数据框转换为 Pandas 数据框,保留分类标签
【发布时间】:2020-03-13 22:21:29
【问题描述】:

我正在使用 sklearn 导入数据:

from sklearn import datasets
dataset = datasets.fetch_openml('credit-g', version = 'active')

sklearn 即时将分类数据转换为数字。

现在我想将此数据集转换为 Pandas DataFrame:

data = pd.DataFrame(dataset.data, columns = dataset.feature_names)
data['class'] = pd.Series(dataset.target)

但此命令会删除所有分类数据 - 它们现在是数字。

我想要的是转换原始文本标签代替数字后的数据框。因此,从 sklearn 数据帧转换为 pandas 数据帧后,数据看起来应该与我只是使用命令下载此数据一样:

pd.read_csv("https://www.openml.org/data/get_csv/31/dataset_31_credit-g.arff")

有可能吗?

【问题讨论】:

    标签: python pandas dataframe scikit-learn


    【解决方案1】:

    fetch_openml的文档中,返回的字典包含:

    [...]
    data : np.array or scipy.sparse.csr_matrix of floats
        The feature matrix. Categorical features are encoded as ordinals.
    [...]
    categories : dict
        Maps each categorical feature name to a list of values, such that the value
        encoded as i is ith in the list.
    [...]
    

    没有不编码分类特征的选项。只要您使用sklearn 下载数据集,您就会有浮点数而不是字符串。

    但是,由于还返回了类别,您可以使用以下类别特征重建“基础”数据集(我不确定它是最快的解决方案,也不是更优雅的解决方案):

    from sklearn import datasets
    import pandas as pd
    import numpy as np
    
    def main():
        dataset = datasets.fetch_openml('credit-g', version = 'active')
    
        raws = [
            np.take(dataset['categories'][feature], dataset['data'][:,i].astype(int))  # Take string value for categorical features
            if feature in dataset['categories'] else dataset['data'][:,i]  # Else use the floats as is
            for i, feature in enumerate(dataset['feature_names'])
        ]
    
        data = pd.DataFrame(np.stack(raws, axis=1), columns=dataset.feature_names)
        data['class'] = pd.Series(dataset.target)
        print("Initial dtypes:")
        print(data.dtypes)
    
        dtypes = {
            f: 'category' if f in dataset['categories'] else 'float'
            for f in dataset['feature_names']
        }
        dtypes['class'] = 'category'
        data = data.astype(dtypes)
        print("\nFirst cast:")
        print(data.dtypes)
    
        int_cols = [1, 4, 12]
        data.iloc[:, int_cols] = data.iloc[:, int_cols].astype('int64')
        print("\nInt cast:")
        print(data.dtypes)
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

    • 谢谢!它炒锅。我还有一个问题。现在我尝试将列类型从对象类型转换为分类和数字类型,但没有任何反应: data.iloc[:,[0,2,3,5,6,7,8,9,10,11,13,14 ,15,16,17,18,19,20]] = data.iloc[:,[0,2,3,5,6,7,8,9,10,11,13,14,15,16, 17,18,19,20]].astype('category') data.iloc[:,[1,4,12]] = data.iloc[:,[1,4,12]].astype(float)列仍然是对象类型。如果我尝试将列 1、4、12 转换为 int64,则会出现错误。
    • @Helios 我用铸件更新了答案。您的 int 错误是字符串 "6.0"int() 构造函数的无效输入。但是,浮点 6.0 是有效输入。所以将所有转换为浮点数,然后转换为 int。我对类别没有问题。
    猜你喜欢
    • 2020-10-05
    • 2020-03-08
    • 2019-07-09
    • 1970-01-01
    • 2020-06-17
    • 2023-04-08
    • 2019-05-14
    • 2014-08-19
    • 2020-06-02
    相关资源
    最近更新 更多