如何将Scikit学习数据集转换为Pandas数据集?


106

如何将数据从Scikit学习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?

Answers:


132

您可以手动使用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'])

3
您可以添加一些文字来解释此代码吗?按照我们的标准,这有些简短。
gung-恢复莫妮卡

1
一些束将feature_names作为ndarray,这将破坏columns参数。

1
数据框缺少“种类”键和值。
mastash3ff

4
这段代码对我来说不起作用。对于columns参数,我需要传递columns = np.append(iris ['feature_names'],'target)。我做错了什么,还是这个答案需要编辑?
乔什·戴维斯

2
不适用于所有数据集,例如load_boston()。这个答案更普遍地起作用:stackoverflow.com/a/46379878/1840471
Max Ghenis


55

对于scikit-learn中的所有数据集,TOMDLt的解决方案不够通用。例如,它不适用于波士顿住房数据集。我提出了另一种更通用的解决方案。也无需使用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())

10

作为一种替代方案,我可以轻松解决问题:

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

基本上,不是从一开始就进行连接,而是使用要素矩阵创建数据框,然后仅将目标列与data ['whatvername']相加,然后从数据集中获取目标值


9

花了我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)

为我的熊猫找回物种


7

否则,使用海洋数据集(它们是实际的熊猫数据框):

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

与scikit学习数据集比较:

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


3

可以使用组合特征和目标变量的其他方法np.column_stack细节

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,则可以replace通过转换target_namesdictionary并添加新列来使用:

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

2

基本上,您需要的是“数据”,并且已将其存储在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)

2

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

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

以我的理解,使用临时发行说明,这适用于乳腺癌,糖尿病,手指,虹膜,linnerud,葡萄酒和california_houses数据集。


2

更新:2020

您可以使用该参数as_frame=True获取熊猫数据帧。

如果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)

1

解决最佳答案并解决我的评论,这是转换的功能

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)

1

无论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'])

这将正常工作


0

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

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将拥有您所需的一切-属性,目标变量和列名


1
TomDLT的解决方案比我上面建议的要优越得多。它做同样的事情,但是非常优雅并且易于理解。用那个!
HakunaMaData

mydata = pd.DataFrame(items[1][1])引发TypeError: 'dict_items' object does not support indexing
SANBI

0

该片段只是基于TomDLT和rolyat已经贡献和解释的语法糖。唯一的区别是将返回一个元组而不是一个字典,并且列名被枚举。load_iris

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

感谢您提供此代码段,它可能会提供一些有限的即时帮助。通过说明为什么这是解决问题的好方法,适当的解释将大大提高其长期价值,对于其他存在类似问题的读者来说,这样做将更为有用。请编辑您的答案以添加一些解释,包括您所做的假设。
再见StackExchange

0
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()

0

最好的方法之一:

data = pd.DataFrame(digits.data)

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


0

我从您的答案中汲取了一些想法,但我不知道如何缩短它的时间:)

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']

这将提供一个带有feature_names和target作为列以及RangeIndex(start = 0,stop = len(df),step = 1)的Pandas DataFrame。我想有一个较短的代码,可以直接添加“目标”。


0

该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)

0

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

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 Series。


0
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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.