Comment convertir un ensemble de données Scikit-learn en un ensemble de données Pandas?


106

Comment convertir les données d'un objet Scikit-learn Bunch en un 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?

Réponses:


132

Manuellement, vous pouvez utiliser le pd.DataFrameconstructeur, en donnant un tableau numpy ( data) et une liste des noms des colonnes ( columns). Pour tout avoir dans un DataFrame, vous pouvez concaténer les fonctionnalités et la cible dans un seul tableau numpy avec np.c_[...](notez le []):

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
Pouvez-vous ajouter un petit texte pour expliquer ce code? C'est un peu bref selon nos normes.
gung - Réintégrer Monica le

1
Certains groupes ont le nom_fonctionnalité comme un ndarray qui cassera le paramètre de colonnes.

1
Clé et valeurs "Espèce" manquantes pour la trame de données.
mastash3ff

4
Ce code ne fonctionnait pas tel quel pour moi. Pour le paramètre des colonnes, j'avais besoin de passer dans les colonnes = np.append (iris ['feature_names'], 'target). Ai-je fait quelque chose de mal ou cette réponse doit-elle être modifiée?
Josh Davis

2
Cela ne fonctionne pas pour tous les ensembles de données, tels que load_boston(). Cette réponse fonctionne plus généralement: stackoverflow.com/a/46379878/1840471
Max Ghenis


55

La solution de TOMDLt n'est pas assez générique pour tous les jeux de données de scikit-learn. Par exemple, cela ne fonctionne pas pour l'ensemble de données sur les logements de Boston. Je propose une solution différente, plus universelle. Pas besoin d'utiliser numpy également.

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

En tant que fonction générale:

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

Juste comme alternative que je pourrais comprendre beaucoup plus facilement:

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

Fondamentalement, au lieu de concaténer dès le départ, créez simplement un cadre de données avec la matrice des fonctionnalités, puis ajoutez simplement la colonne cible avec les données ['whatvername'] et récupérez les valeurs cibles de l'ensemble de données


9

Il m'a fallu 2 heures pour comprendre cela

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)

Récupérez les espèces pour mes pandas


7

Sinon, utilisez des ensembles de données Seaborn qui sont de véritables trames de données pandas:

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

Comparez avec les ensembles de données 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']

4

Cela fonctionne pour moi.

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

3

Une autre façon de combiner des fonctionnalités et des variables cibles peut être d'utiliser np.column_stack( détails )

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

Résultat:

   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

Si vous avez besoin de l'étiquette de chaîne pour la target, vous pouvez utiliser replaceen convertissant target_namespour dictionaryet ajouter une nouvelle colonne:

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

Résultat:

   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

Fondamentalement, ce dont vous avez besoin, ce sont les "données", et vous les avez dans le groupe scikit, maintenant vous avez juste besoin de la "cible" (prédiction) qui est également dans le groupe.

Il suffit donc de concaténer ces deux pour rendre les données complètes

  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

Depuis la version 0.23, vous pouvez directement renvoyer un DataFrame à l'aide de l' as_frameargument. Par exemple, charger l'ensemble de données d'iris:

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

D'après ce que je comprends, en utilisant les notes de publication provisoires , cela fonctionne pour les ensembles de données breast_cancer, diabète, digits, iris, linnerud, wine et california_houses.


2

Mise à jour: 2020

Vous pouvez utiliser le paramètre as_frame=Truepour obtenir des dataframes pandas.

Si le paramètre as_frame est disponible (par exemple 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

Si le paramètre as_frame n'est PAS disponible (par exemple, 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

En travaillant sur la meilleure réponse et en répondant à mon commentaire, voici une fonction pour la conversion

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

Quelle que soit la réponse de TomDLT, cela peut ne pas fonctionner pour certains d'entre vous car

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

parce que iris ['feature_names'] vous renvoie un tableau numpy. Dans le tableau numpy, vous ne pouvez pas ajouter un tableau et une liste ['cible'] par juste + opérateur. Par conséquent, vous devez d'abord le convertir en une liste, puis l'ajouter.

Tu peux faire

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

Cela fonctionnera bien.


0

Il y a peut-être un meilleur moyen, mais voici ce que j'ai fait dans le passé et cela fonctionne assez bien:

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

Maintenant, mydata aura tout ce dont vous avez besoin - attributs, variables cibles et noms de colonnes


1
La solution de TomDLT est bien supérieure à ce que je suggère ci-dessus. Il fait la même chose mais est très élégant et facile à comprendre. Utiliser ça!
HakunaMaData

mydata = pd.DataFrame(items[1][1])lancersTypeError: 'dict_items' object does not support indexing
SANBI échantillonne le

0

Cet extrait de code n'est que du sucre syntaxique basé sur ce que TomDLT et rolyat ont déjà contribué et expliqué. Les seules différences seraient que load_iriscela renverra un tuple au lieu d'un dictionnaire et les noms de colonnes sont énumérés.

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

Merci pour cet extrait de code, qui pourrait fournir une aide limitée et immédiate. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez faites.
Goodbye 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

L'un des meilleurs moyens:

data = pd.DataFrame(digits.data)

Digits est le dataframe sklearn et je l'ai converti en un pandas DataFrame


0

J'ai pris quelques idées de vos réponses et je ne sais pas comment raccourcir :)

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

Cela donne un Pandas DataFrame avec feature_names plus target en tant que colonnes et RangeIndex (start = 0, stop = len (df), step = 1). Je voudrais avoir un code plus court où je peux ajouter directement la «cible».


0

L'API est un peu plus propre que les réponses suggérées. Ici, en utilisant as_frameet en veillant à inclure également une colonne de réponse.

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

Voici un autre exemple de méthode intégrée qui peut être utile.

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)

Les données iris_X sont importées en tant que pandas DataFrame et la cible iris_y est importée en tant que 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()
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.