Como converter um conjunto de dados Scikit-learn em um conjunto de dados Pandas?


106

Como faço para converter dados de um objeto Scikit-learn Bunch em um 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?

Respostas:


132

Manualmente, você pode usar o pd.DataFrameconstrutor, fornecendo um array numpy ( data) e uma lista dos nomes das colunas ( columns). Para ter tudo em um DataFrame, você pode concatenar os recursos e o destino em uma matriz numpy com np.c_[...](observe o []):

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
Você pode adicionar um pequeno texto para explicar este código? Isso é um tanto breve para nossos padrões.
gung - Reintegrar Monica em

1
Alguns grupos têm o feature_names como um ndarray que quebrará o parâmetro das colunas.

1
Chave e valores "Espécies" ausentes para o dataframe.
mastash3ff

4
Este código não funcionou como está para mim. Para o parâmetro de colunas, eu precisava passar colunas = np.append (iris ['feature_names'], 'target). Fiz algo errado ou esta resposta precisa de uma edição?
Josh Davis,

2
Isso não funciona para todos os conjuntos de dados, como load_boston(). Esta resposta funciona de maneira mais geral: stackoverflow.com/a/46379878/1840471
Max Ghenis


55

A solução do TOMDLt não é genérica o suficiente para todos os conjuntos de dados no scikit-learn. Por exemplo, não funciona para o conjunto de dados de habitação de Boston. Proponho uma solução diferente que é mais universal. Não há necessidade de usar numpy também.

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

Como função geral:

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

Apenas como uma alternativa em que eu poderia entender muito mais facilmente:

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

Basicamente, em vez de concatenar desde o início, basta fazer um quadro de dados com a matriz de recursos e, em seguida, apenas adicionar a coluna de destino com os dados ['whatvername'] e pegar os valores de destino do conjunto de dados


9

Levei 2 horas para descobrir isso

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)

Recupere as espécies para meus pandas


7

Caso contrário, use conjuntos de dados marítimos que são frames de dados reais do pandas:

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

Compare com os conjuntos de dados do 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

Isso funciona para mim.

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

3

Outra maneira de combinar recursos e variáveis ​​de destino pode ser usando np.column_stack( detalhes )

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

Resultado:

   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 você precisa a etiqueta de string para o target, então você pode usar replaceatravés da conversão target_namespara dictionarye adicionar uma nova coluna:

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

Resultado:

   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

Basicamente, o que você precisa são os "dados", e você os tem no grupo do scikit, agora você precisa apenas do "alvo" (previsão) que também está no grupo.

Então, só precisa concatá-los para tornar os dados completos

  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 partir da versão 0.23, você pode retornar um DataFrame diretamente usando o as_frameargumento. Por exemplo, carregando o conjunto de dados da íris:

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

No meu entendimento, usando as notas de versão provisórias , isso funciona para os conjuntos de dados breast_cancer, diabetes, digits, iris, linnerud, wine e california_houses.


2

Atualização: 2020

Você pode usar o parâmetro as_frame=Truepara obter dataframes do pandas.

Se o parâmetro as_frame estiver disponível (por exemplo, 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 o parâmetro as_frame NÃO estiver disponível (por exemplo, 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

Trabalhando na melhor resposta e respondendo ao meu comentário, aqui está uma função para a conversão

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

Seja o que for que o TomDLT respondeu, pode não funcionar para alguns de vocês porque

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

porque iris ['feature_names'] retorna um array numpy. Em numpy array você não pode adicionar um array e uma lista ['destino'] apenas pelo operador +. Portanto, você precisa primeiro convertê-lo em uma lista e depois adicionar.

Você pode fazer

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

Isso vai funcionar bem, embora ..


0

Pode haver uma maneira melhor, mas aqui está o que eu fiz no passado e funciona muito bem:

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

Agora mydata terá tudo que você precisa - atributos, variáveis ​​de destino e nomes de colunas


1
A solução da TomDLT é muito superior ao que estou sugerindo acima. Ele faz a mesma coisa, mas é muito elegante e fácil de entender. Use isso!
HakunaMaData

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

0

Este snippet é apenas uma adição sintática construída sobre o que TomDLT e rolyat já contribuíram e explicaram. As únicas diferenças seriam que load_irisretornariam uma tupla em vez de um dicionário e os nomes das colunas seriam enumerados.

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

Obrigado por este trecho de código, que pode fornecer alguma ajuda limitada e imediata. Uma explicação adequada melhoraria muito seu valor a longo prazo , mostrando por que essa é uma boa solução para o problema, e a tornaria mais útil para leitores futuros com outras questões semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
Adeus 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

Uma das melhores maneiras:

data = pd.DataFrame(digits.data)

Digits é o dataframe sklearn e eu o converti em um DataFrame do pandas


0

Tirei algumas ideias das suas respostas e não sei como torná-las mais curtas :)

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

Isso dá um Pandas DataFrame com feature_names mais o destino como colunas e RangeIndex (start = 0, stop = len (df), step = 1). Eu gostaria de ter um código mais curto, onde posso ter 'destino' adicionado diretamente.


0

A API é um pouco mais limpa do que as respostas sugeridas. Aqui, usando as_framee certificando-se de incluir uma coluna de resposta também.

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

Aqui está outro exemplo de método integrado que pode ser útil.

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)

Os dados iris_X são importados como pandas DataFrame e os dados iris_y são importados como 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()
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.