Come convertire un set di dati di Scikit in un set di dati di Panda?


106

Come si convertono i dati da un oggetto Bunch di Scikit-learn a 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?

Risposte:


132

Manualmente, puoi usare il pd.DataFramecostruttore, fornendo un array numpy ( data) e un elenco dei nomi delle colonne ( columns). Per avere tutto in un DataFrame, puoi concatenare le caratteristiche e l'obiettivo in un array numpy con np.c_[...](nota il []):

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
Puoi aggiungere un breve testo per spiegare questo codice? Questo è piuttosto breve per i nostri standard.
gung - Ripristina Monica il

1
Alcuni grappoli hanno il feature_names come ndarray che interromperà il parametro column.

1
Chiave e valori "Specie" mancanti per dataframe.
mastash3ff

4
Questo codice non ha funzionato così com'è per me. Per il parametro colonne, dovevo passare colonne = np.append (iris ['feature_names'], 'target). Ho fatto qualcosa di sbagliato o questa risposta necessita di una modifica?
Josh Davis

2
Questo non funziona per tutti i set di dati, come load_boston(). Questa risposta funziona più in generale: stackoverflow.com/a/46379878/1840471
Max Ghenis


55

La soluzione di TOMDLt non è abbastanza generica per tutti i set di dati in scikit-learn. Ad esempio, non funziona per il set di dati sulle abitazioni di Boston. Propongo una soluzione diversa, più universale. Non c'è bisogno di usare anche 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()

Come funzione generale:

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

Proprio come un'alternativa che potrei avvolgere la mia testa molto più facilmente:

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

Fondamentalmente invece di concatenare dall'inizio, crea un frame di dati con la matrice delle caratteristiche e poi aggiungi semplicemente la colonna di destinazione con i dati ['whatvername'] e prendi i valori di destinazione dal set di dati


9

Mi ci sono volute 2 ore per capirlo

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)

Riprenditi la specie per i miei panda


7

Altrimenti usa set di dati seaborn che sono frame di dati panda reali:

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

Confronta con scikit learn data set:

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

Questo funziona per me.

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

3

Un altro modo per combinare le caratteristiche e le variabili di destinazione può essere l'uso di np.column_stack( dettagli )

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

Risultato:

   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

Se hai bisogno dell'etichetta della stringa per target, puoi usare replaceconvertendo target_namesin dictionarye aggiungendo una nuova colonna:

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

Risultato:

   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

Fondamentalmente ciò di cui hai bisogno sono i "dati", e li hai nel gruppo scikit, ora hai bisogno solo del "bersaglio" (previsione) che è anche nel gruppo.

Quindi è sufficiente concatenare questi due per completare i dati

  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

A partire dalla versione 0.23, puoi restituire direttamente un DataFrame utilizzando l' as_frameargomento. Ad esempio, caricamento del set di dati dell'iride:

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

Nella mia comprensione utilizzando le note di rilascio provvisorie , questo funziona per i set di dati di cancro al seno, diabete, digits, iris, linnerud, vino e california_houses.


2

Aggiornamento: 2020

È possibile utilizzare il parametro as_frame=Trueper ottenere i dataframe dei panda.

Se è disponibile il parametro as_frame (ad es. 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

Se il parametro as_frame NON è disponibile (es. 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

Elaborando la risposta migliore e affrontando il mio commento, ecco una funzione per la conversione

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

Qualunque cosa abbia risposto TomDLT, potrebbe non funzionare per alcuni di voi perché

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

perché iris ['feature_names'] ti restituisce un array numpy. In numpy array non puoi aggiungere un array e una lista ['target'] solo con l'operatore +. Quindi devi prima convertirlo in un elenco e poi aggiungere.

Tu puoi fare

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

Funzionerà bene anche se ..


0

Potrebbe esserci un modo migliore, ma ecco cosa ho fatto in passato e funziona abbastanza bene:

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

Ora mydata avrà tutto ciò di cui hai bisogno: attributi, variabile di destinazione e nomi di colonna


1
La soluzione di TomDLT è molto superiore a quanto suggerisco sopra. Fa la stessa cosa ma è molto elegante e di facile comprensione. Usa quello!
HakunaMaData

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

0

Questo frammento è solo zucchero sintattico costruito su ciò che TomDLT e rolyat hanno già contribuito e spiegato. Le uniche differenze sarebbero che load_irisrestituirà una tupla invece di un dizionario e i nomi delle colonne saranno enumerati.

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

Grazie per questo snippet di codice, che potrebbe fornire un aiuto limitato e immediato. Una spiegazione adeguata migliorerebbe notevolmente il suo valore a lungo termine mostrando perché questa è una buona soluzione al problema e la renderebbe più utile per i futuri lettori con altre domande simili. Si prega di modificare la risposta di aggiungere qualche spiegazione, tra le ipotesi che hai fatto.
Arrivederci 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

Uno dei modi migliori:

data = pd.DataFrame(digits.data)

Digits è il dataframe di sklearn e l'ho convertito in un DataFrame panda


0

Ho preso un paio di idee dalle tue risposte e non so come renderle più brevi :)

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

Questo dà un Pandas DataFrame con feature_names più target come colonne e RangeIndex (start = 0, stop = len (df), step = 1). Vorrei avere un codice più breve in cui posso aggiungere direttamente "target".


0

L'API è un po 'più pulita delle risposte suggerite. Qui, usando as_framee assicurandoti di includere anche una colonna di risposta.

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

Ecco un altro esempio di metodo integrato che potrebbe essere 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)

I dati iris_X vengono importati come DataFrame panda e il target iris_y viene importato come serie panda.


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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.