【问题标题】:How to convert a Scikit-learn dataset to a Pandas dataset如何将 Scikit-learn 数据集转换为 Pandas 数据集
【发布时间】:2016-11-01 12:17:37
【问题描述】:

如何将数据从 Scikit-learn Bunch 对象转换为 Pandas DataFrame?

from sklearn.datasets import load_iris
import pandas as pd
data = load_iris()
print(type(data))
data1 = pd. # Is there a Pandas method to accomplish this?

【问题讨论】:

    标签: python pandas scikit-learn dataset


    【解决方案1】:

    您可以手动使用pd.DataFrame 构造函数,给出一个numpy 数组(data)和一个列名列表(columns)。 要将所有内容都放在一个 DataFrame 中,您可以使用 np.c_[...] 将特征和目标连接到一个 numpy 数组中(注意 []):

    import numpy as np
    import pandas as pd
    from sklearn.datasets import load_iris
    
    # save load_iris() sklearn dataset to iris
    # if you'd like to check dataset type use: type(load_iris())
    # if you'd like to view list of attributes use: dir(load_iris())
    iris = load_iris()
    
    # np.c_ is the numpy concatenate function
    # which is used to concat iris['data'] and iris['target'] arrays 
    # for pandas column argument: concat iris['feature_names'] list
    # and string list (in this case one string); you can make this anything you'd like..  
    # the original dataset would probably call this ['Species']
    data1 = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                         columns= iris['feature_names'] + ['target'])
    

    【讨论】:

    • 你能添加一点文字来解释这段代码吗?按照我们的标准,这有点简短。
    • 有些束将 feature_names 作为 ndarray,这会破坏 columns 参数。
    • 缺少数据框的“物种”键和值。
    • 这段代码对我来说不起作用。对于 columns 参数,我需要传入 columns=np.append(iris['feature_names'], 'target)。我做错了什么,还是这个答案需要修改?
    • 这不适用于所有数据集,例如load_boston()。这个答案更普遍:stackoverflow.com/a/46379878/1840471
    【解决方案2】:
    from sklearn.datasets import load_iris
    import pandas as pd
    
    data = load_iris()
    df = pd.DataFrame(data=data.data, columns=data.feature_names)
    df.head()
    

    可能对本教程感兴趣:http://www.neural.cz/dataset-exploration-boston-house-pricing.html

    【讨论】:

    • 需要将数据与目标拼接起来:df = pd.DataFrame(np.concatenate((iris.data, np.array([iris.target]).T), axis=1), columns=iris.feature_names + ['target'])
    【解决方案3】:

    TOMDLt 的解决方案对于 scikit-learn 中的所有数据集都不够通用。例如,它不适用于波士顿住房数据集。我提出了一个更通用的不同解决方案。也不需要使用 numpy。

    from sklearn import datasets
    import pandas as pd
    
    boston_data = datasets.load_boston()
    df_boston = pd.DataFrame(boston_data.data,columns=boston_data.feature_names)
    df_boston['target'] = pd.Series(boston_data.target)
    df_boston.head()
    

    作为一般功能:

    def sklearn_to_df(sklearn_dataset):
        df = pd.DataFrame(sklearn_dataset.data, columns=sklearn_dataset.feature_names)
        df['target'] = pd.Series(sklearn_dataset.target)
        return df
    
    df_boston = sklearn_to_df(datasets.load_boston())
    

    【讨论】:

    • 我觉得pd.Series(sklearn_dataset.target)可以换成sklearn_dataset.target?至少它适用于我的 pandas 1.1.3
    • 我觉得这个解决方案更容易理解
    【解决方案4】:

    我花了 2 个小时才弄明白

    import numpy as np
    import pandas as pd
    from sklearn.datasets import load_iris
    
    iris = load_iris()
    ##iris.keys()
    
    
    df= pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                     columns= iris['feature_names'] + ['target'])
    
    df['species'] = pd.Categorical.from_codes(iris.target, iris.target_names)
    

    为我的熊猫取回物种

    【讨论】:

      【解决方案5】:

      作为一种替代方法,我可以更轻松地绕开我的脑袋:

      data = load_iris()
      df = pd.DataFrame(data['data'], columns=data['feature_names'])
      df['target'] = data['target']
      df.head()
      

      基本上不是从一开始就连接,只需使用特征矩阵制作一个数据框,然后将目标列与 data['whatvername'] 添加并从数据集中获取目标值

      【讨论】:

      • 简单的答案是最好的...
      【解决方案6】:

      否则使用seaborn data sets 这是实际的熊猫数据框:

      import seaborn
      iris = seaborn.load_dataset("iris")
      type(iris)
      # <class 'pandas.core.frame.DataFrame'>
      

      与 scikit learn 数据集比较:

      from sklearn import datasets
      iris = datasets.load_iris()
      type(iris)
      # <class 'sklearn.utils.Bunch'>
      dir(iris)
      # ['DESCR', 'data', 'feature_names', 'filename', 'target', 'target_names']
      

      【讨论】:

        【解决方案7】:

        这对我来说很简单。

        boston = load_boston()
        boston_frame = pd.DataFrame(data=boston.data, columns=boston.feature_names)
        boston_frame["target"] = boston.target
        

        但这也可以应用于 load_iris。

        【讨论】:

        • 这对我来说很有魅力!
        【解决方案8】:

        新更新

        您可以使用参数as_frame=True 来获取pandas 数据帧。

        如果 as_frame 参数可用(例如 load_iris)

        from sklearn import datasets
        X,y = datasets.load_iris(return_X_y=True) # numpy arrays
        
        dic_data = datasets.load_iris(as_frame=True)
        print(dic_data.keys())
        
        df = dic_data['frame'] # pandas dataframe data + target
        df_X = dic_data['data'] # pandas dataframe data only
        ser_y = dic_data['target'] # pandas series target only
        dic_data['target_names'] # numpy array
        
        

        如果 as_frame 参数不可用(例如 load_boston)

        from sklearn import datasets
        
        fnames = [ i for i in dir(datasets) if 'load_' in i]
        print(fnames)
        
        fname = 'load_boston'
        loader = getattr(datasets,fname)()
        df = pd.DataFrame(loader['data'],columns= loader['feature_names'])
        df['target'] = loader['target']
        df.head(2)
        

        【讨论】:

        • 最后 - 可以加载 boston 而不仅仅是 iris 等!这种分割非常清晰,效果很好。
        【解决方案9】:

        这对我有用。

        dataFrame = pd.dataFrame(data = np.c_[ [iris['data'],iris['target'] ],
        columns=iris['feature_names'].tolist() + ['target'])
        

        【讨论】:

          【解决方案10】:

          结合特征和目标变量的其他方式可以使用np.column_stack (details)

          import numpy as np
          import pandas as pd
          from sklearn.datasets import load_iris
          
          data = load_iris()
          df = pd.DataFrame(np.column_stack((data.data, data.target)), columns = data.feature_names+['target'])
          print(df.head())
          

          结果:

             sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)     target
          0                5.1               3.5                1.4               0.2     0.0
          1                4.9               3.0                1.4               0.2     0.0 
          2                4.7               3.2                1.3               0.2     0.0 
          3                4.6               3.1                1.5               0.2     0.0
          4                5.0               3.6                1.4               0.2     0.0
          

          如果您需要target 的字符串标签,则可以通过将target_names 转换为dictionary 并添加新列来使用replace

          df['label'] = df.target.replace(dict(enumerate(data.target_names)))
          print(df.head())
          

          结果:

             sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)     target  label 
          0                5.1               3.5                1.4               0.2     0.0     setosa
          1                4.9               3.0                1.4               0.2     0.0     setosa
          2                4.7               3.2                1.3               0.2     0.0     setosa
          3                4.6               3.1                1.5               0.2     0.0     setosa
          4                5.0               3.6                1.4               0.2     0.0     setosa
          

          【讨论】:

            【解决方案11】:

            从 0.23 版开始,您可以使用 as_frame 参数直接返回 DataFrame。 比如加载虹膜数据集:

            from sklearn.datasets import load_iris
            iris = load_iris(as_frame=True)
            df = iris.data
            

            据我了解,使用 provisionally release notes,这适用于乳腺癌、糖尿病、数字、虹膜、linnerud、wine 和 california_houses 数据集。

            【讨论】:

              【解决方案12】:

              这是另一个集成方法示例可能会有所帮助。

              from sklearn.datasets import load_iris
              iris_X, iris_y = load_iris(return_X_y=True, as_frame=True)
              type(iris_X), type(iris_y)
              

              数据 iris_X 被导入为 pandas DataFrame 和 目标 iris_y 被导入为 pandas 系列。

              【讨论】:

                【解决方案13】:

                许多解决方案要么缺少列名,要么缺少物种目标名称。此解决方案提供 target_name 标签。

                @Ankit-mathanker 的解决方案有效,但它会迭代 Dataframe Series 'target_names' 以将 iris 物种替换为整数标识符。

                基于格言“Don't iterate a Dataframe if you don't have to”,以下解决方案利用 pd.replace() 更简洁地完成替换。

                import pandas as pd
                from sklearn.datasets import load_iris
                
                iris = load_iris()
                df = pd.DataFrame(iris['data'], columns = iris['feature_names'])
                df['target'] = pd.Series(iris['target'], name = 'target_values')
                df['target_name'] = df['target'].replace([0,1,2],
                ['iris-' + species for species in iris['target_names'].tolist()])
                
                df.head(3)
                
                sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target target_name
                0 5.1 3.5 1.4 0.2 0 iris-setosa
                1 4.9 3.0 1.4 0.2 0 iris-setosa
                2 4.7 3.2 1.3 0.2 0 iris-setosa

                【讨论】:

                • 这就是答案
                【解决方案14】:

                基本上您需要的是“数据”,并且您在 scikit 束中拥有它,现在您只需要也在束中的“目标”(预测)。

                所以只需要将这两者连接起来就可以使数据完整了

                  data_df = pd.DataFrame(cancer.data,columns=cancer.feature_names)
                  target_df = pd.DataFrame(cancer.target,columns=['target'])
                
                  final_df = data_df.join(target_df)
                

                【讨论】:

                  【解决方案15】:

                  API 比建议的响应要干净一些。在这里,使用as_frame 并确保也包含一个响应列。

                  import pandas as pd
                  from sklearn.datasets import load_wine
                  
                  features, target = load_wine(as_frame=True).data, load_wine(as_frame=True).target
                  df = features
                  df['target'] = target
                  
                  df.head(2)
                  

                  【讨论】:

                    【解决方案16】:

                    找出最佳答案并解决我的评论,这是一个转换函数

                    def bunch_to_dataframe(bunch):
                      fnames = bunch.feature_names
                      features = fnames.tolist() if isinstance(fnames, np.ndarray) else fnames
                      features += ['target']
                      return pd.DataFrame(data= np.c_[bunch['data'], bunch['target']],
                                     columns=features)
                    

                    【讨论】:

                      【解决方案17】:

                      无论 TomDLT 回答什么,它可能对你们中的一些人不起作用,因为

                      data1 = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                                       columns= iris['feature_names'] + ['target'])
                      

                      因为 iris['feature_names'] 返回一个 numpy 数组。在 numpy 数组中,您不能仅通过 + 运算符添加数组和列表 ['target']。因此,您需要先将其转换为列表,然后再添加。

                      你可以的

                      data1 = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                                       columns= list(iris['feature_names']) + ['target'])
                      

                      这会很好用..

                      【讨论】:

                        【解决方案18】:

                        可能有更好的方法,但这是我过去所做的并且效果很好:

                        items = data.items()                          #Gets all the data from this Bunch - a huge list
                        mydata = pd.DataFrame(items[1][1])            #Gets the Attributes
                        mydata[len(mydata.columns)] = items[2][1]     #Adds a column for the Target Variable
                        mydata.columns = items[-1][1] + [items[2][0]] #Gets the column names and updates the dataframe
                        

                        现在 mydata 将拥有您需要的一切 - 属性、目标变量和列名

                        【讨论】:

                        • TomDLT 的解决方案比我上面建议的要好得多。它做同样的事情,但非常优雅且易于理解。使用它!
                        • mydata = pd.DataFrame(items[1][1]) throws TypeError: 'dict_items' object does not support indexing
                        【解决方案19】:

                        这个 sn-p 只是 syntactic sugar 建立在 TomDLT and rolyat 已经贡献和解释的基础上。唯一的区别是load_iris 将返回一个元组而不是一个字典,并且列名是枚举的。

                        df = pd.DataFrame(np.c_[load_iris(return_X_y=True)])
                        

                        【讨论】:

                        • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation would greatly improve its long-term value 通过展示为什么这是一个很好的解决问题的方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
                        【解决方案20】:
                        import pandas as pd
                        from sklearn.datasets import load_iris
                        iris = load_iris()
                        X = iris['data']
                        y = iris['target']
                        iris_df = pd.DataFrame(X, columns = iris['feature_names'])
                        iris_df.head()
                        

                        【讨论】:

                          【解决方案21】:

                          最好的方法之一:

                          data = pd.DataFrame(digits.data)
                          

                          Digits 是 sklearn 数据帧,我将其转换为 pandas 数据帧

                          【讨论】:

                            【解决方案22】:

                            我从你的回答中得到了几个想法,但我不知道如何让它更短:)

                            import pandas as pd
                            from sklearn.datasets import load_iris
                            iris = load_iris()
                            df = pd.DataFrame(iris.data, columns=iris['feature_names'])
                            df['target'] = iris['target']
                            

                            这给出了一个 Pandas DataFrame,其中 feature_names 加上 target 作为列和 RangeIndex(start=0, stop=len(df), step=1)。 我想要一个更短的代码,我可以直接添加“目标”。

                            【讨论】:

                              【解决方案23】:
                              from sklearn.datasets import load_iris
                              import pandas as pd
                              
                              iris_dataset = load_iris()
                              
                              datasets = pd.DataFrame(iris_dataset['data'], columns = 
                                         iris_dataset['feature_names'])
                              target_val = pd.Series(iris_dataset['target'], name = 
                                          'target_values')
                              
                              species = []
                              for val in target_val:
                                  if val == 0:
                                      species.append('iris-setosa')
                                  if val == 1:
                                      species.append('iris-versicolor')
                                  if val == 2:
                                      species.append('iris-virginica')
                              species = pd.Series(species)
                              
                              datasets['target'] = target_val
                              datasets['target_name'] = species
                              datasets.head()
                              

                              【讨论】:

                                【解决方案24】:

                                您可以使用 pd.DataFrame 构造函数,给出一个 numpy 数组(数据)和一个列名称列表(列)。要将所有内容都放在一个 DataFrame 中,您可以使用 np.c_[...] 将特征和目标连接到一个 numpy 数组中(注意方括号而不是括号)。此外,如果在连接之前不将特征名称 (iris['feature_names']) 转换为列表,您可能会遇到一些麻烦:

                                import numpy as np
                                import pandas as pd
                                from sklearn.datasets import load_iris
                                
                                iris = load_iris()
                                
                                df = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                                                     columns= list(iris['feature_names']) + ['target'])
                                

                                【讨论】:

                                  【解决方案25】:

                                  对这个问题有很多很好的回答;我在下面添加了自己的。

                                  import pandas as pd
                                  from sklearn.datasets import load_iris
                                  
                                  df = pd.DataFrame(
                                      # load all 4 dimensions of the dataframe EXCLUDING species data
                                      load_iris()['data'],
                                      # set the column names for the 4 dimensions of data
                                      columns=load_iris()['feature_names']
                                  )
                                  
                                  # we create a new column called 'species' with 150 rows of numerical data 0-2 signifying a species type. 
                                  # Our column `species` should have data such `[0, 0, 1, 2, 1, 0]` etc.
                                  df['species'] = load_iris()['target']
                                  # we map the numerical data to string data for species type
                                  df['species'] = df['species'].map({
                                      0 : 'setosa',
                                      1 : 'versicolor',
                                      2 : 'virginica'   
                                  })
                                  
                                  df.head()
                                  

                                  故障

                                  • 由于某种原因,load_iris['feature_names] 只有 4 列(萼片长度、萼片宽度、花瓣长度、花瓣宽度);此外,load_iris['data'] 仅包含上述feature_names 的数据。
                                  • 相反,物种列名存储在load_iris()['target_names'] == array(['setosa', 'versicolor', 'virginica']
                                  • 除此之外,物种行数据存储在load_iris()['target'].nunique() == 3
                                  • 我们的目标只是添加一个名为species 的新列,该列使用map 函数将数字数据0-2 转换为表示鸢尾花种类的3 种字符串数据。

                                  【讨论】:

                                    猜你喜欢
                                    • 2014-04-29
                                    • 2015-10-23
                                    • 2018-07-23
                                    • 2021-02-12
                                    • 2015-04-14
                                    • 2016-07-13
                                    • 2019-04-05
                                    • 2022-06-18
                                    • 2021-07-21
                                    相关资源
                                    最近更新 更多