Jak przekonwertować zestaw danych Scikit-Learn na zestaw danych Pandas?

107

Jak przekonwertować dane z obiektu Scikit-Learn Bunch na 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?
Próbki SANBI
źródło

Odpowiedzi:

134

Ręcznie możesz użyć pd.DataFramekonstruktora, podając tablicę numpy ( data) i listę nazw kolumn ( columns). Aby mieć wszystko w jednej ramce DataFrame, możesz połączyć funkcje i cel w jedną tablicę numpy za pomocą np.c_[...](zwróć uwagę na []):

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'])
TomDLT
źródło
3
Czy możesz dodać trochę tekstu, aby wyjaśnić ten kod? To jest trochę krótkie jak na nasze standardy.
gung - Przywróć Monikę
1
Niektóre paczki mają nazwy feature_names jako ndarray, co spowoduje przerwanie parametru column.
1
Brak klucza i wartości „Gatunki” w ramce danych.
mastash3ff,
4
Ten kod nie działał tak, jak jest dla mnie. W przypadku parametru kolumny musiałem przekazać kolumny = np.append (iris ['feature_names'], 'target). Czy zrobiłem coś źle, czy ta odpowiedź wymaga edycji?
Josh Davis
2
Nie działa to w przypadku wszystkich zestawów danych, takich jak load_boston(). Ta odpowiedź działa bardziej ogólnie: stackoverflow.com/a/46379878/1840471
Max Ghenis
78
from sklearn.datasets import load_iris
import pandas as pd

data = load_iris()
df = pd.DataFrame(data.data, columns=data.feature_names)
df.head()

Ten samouczek może Cię zainteresować: http://www.neural.cz/dataset-exploration-boston-house-pricing.html

justin4480
źródło
11
Trzeba połączyć dane z celem: df = pd.DataFrame (np.concatenate ((iris.data, np.array ([iris.target]). T), axis = 1), columns = iris.feature_names + [' target '])
Tyler 傲 来 国 主
56

Rozwiązanie TOMDLt nie jest wystarczająco ogólne dla wszystkich zestawów danych w scikit-learn. Na przykład nie działa w przypadku zbioru danych dotyczących mieszkań bostońskich. Proponuję inne, bardziej uniwersalne rozwiązanie. Nie ma też potrzeby używania 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()

Jako funkcja ogólna:

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())
Nilav Baran Ghosh
źródło
10

Jako alternatywa, którą mógłbym znacznie łatwiej owinąć głową:

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

Zasadniczo zamiast łączyć od samego początku, wystarczy utworzyć ramkę danych z macierzą funkcji, a następnie po prostu dodać kolumnę docelową z danymi [„whatvername”] i pobrać wartości docelowe z zestawu danych

daguito81
źródło
9

Zajęło mi to 2 godziny, żeby to rozgryźć

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)

Odzyskaj gatunki dla moich pand

Victor Tong
źródło
7

W przeciwnym razie użyj zbiorów danych dotyczących porodów morskich, które są rzeczywistymi ramkami danych pand:

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

Porównaj z zestawami danych 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']
Paul Rougieux
źródło
4

To działa dla mnie.

dataFrame = pd.dataFrame(data = np.c_[ [iris['data'],iris['target'] ],
columns=iris['feature_names'].tolist() + ['target'])
Mukul Aggarwal
źródło
3

Innym sposobem łączenia funkcji i zmiennych docelowych może być użycie np.column_stack( szczegóły )

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

Wynik:

   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

Jeśli potrzebujesz etykiety ciągu dla target, możesz użyć replace, konwertując target_namesna dictionaryi dodając nową kolumnę:

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

Wynik:

   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
student
źródło
2

Zasadniczo potrzebujesz "danych" i masz je w paczce scikit, teraz potrzebujesz tylko "celu" (przewidywania), który również znajduje się w paczce.

Więc wystarczy połączyć te dwa, aby dane były kompletne

  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)
Dhiraj Himani
źródło
2

Od wersji 0.23 możesz bezpośrednio zwrócić ramkę DataFrame przy użyciu as_frameargumentu. Na przykład ładowanie zestawu danych tęczówki:

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

W moim rozumieniu, korzystając z informacji o tymczasowym wydaniu , działa to dla zestawów danych dotyczących raka piersi, cukrzycy, cyfr, tęczówki, linnerud, wina i california_houses.

dheinz
źródło
2

Aktualizacja: 2020

Możesz użyć tego parametru, as_frame=Trueaby pobrać ramki danych pandy.

Jeśli dostępny jest parametr as_frame (np. 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

Jeśli parametr as_frame NIE jest dostępny (np. 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)
Bhishan Poudel
źródło
1

Opracowując najlepszą odpowiedź i odnosząc się do mojego komentarza, oto funkcja konwersji

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)

źródło
1

Cokolwiek TomDLT odpowiedział, może nie działać dla niektórych z was, ponieważ

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

ponieważ iris ['feature_names'] zwraca tablicę numpy. W tablicy numpy nie możesz dodać tablicy i listy ['cel'] za pomocą samego operatora +. Dlatego musisz najpierw przekonwertować go na listę, a następnie dodać.

Możesz to zrobić

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

To zadziała dobrze, chociaż ...

Himanshu Poddar
źródło
0

Może być lepszy sposób, ale oto, co zrobiłem w przeszłości i działa całkiem dobrze:

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

Teraz moje dane będą miały wszystko, czego potrzebujesz - atrybuty, zmienną docelową i nazwy kolumn

HakunaMaData
źródło
1
Rozwiązanie firmy TomDLT jest znacznie lepsze niż to, co sugeruję powyżej. Robi to samo, ale jest bardzo elegancki i łatwy do zrozumienia. Użyć tego!
HakunaMaData
mydata = pd.DataFrame(items[1][1])rzucaTypeError: 'dict_items' object does not support indexing
próbki SANBI
0

Ten fragment jest jedynie cukrem syntaktycznym zbudowanym na podstawie tego, co TomDLT i rolyat już wnieśli i wyjaśnili. Jedyna różnica polega na tym, że load_iriszamiast słownika zwróci krotkę, a nazwy kolumn zostaną wyliczone.

df = pd.DataFrame(np.c_[load_iris(return_X_y=True)])
Jeff Hernandez
źródło
Dziękujemy za ten fragment kodu, który może zapewnić ograniczoną, natychmiastową pomoc. Właściwe wyjaśnienie byłoby znacznie poprawić swoją długoterminową wartość pokazując dlaczego jest to dobre rozwiązanie problemu, a byłoby bardziej użyteczne dla czytelników przyszłości z innymi, podobnymi pytaniami. Proszę edytować swoją odpowiedź dodać kilka wyjaśnień, w tym założeń już wykonanych.
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()
Manideep Pullalachervu
źródło
0

Jeden z najlepszych sposobów:

data = pd.DataFrame(digits.data)

Digits to sklearn dataframe i przekonwertowałem ją na pandas DataFrame

Shilp Baroda
źródło
0

Wziąłem kilka pomysłów z Twoich odpowiedzi i nie wiem, jak to skrócić :)

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

Daje to Pandas DataFrame z nazwami_funkcji oraz celem jako kolumnami i RangeIndex (start = 0, stop = len (df), step = 1). Chciałbym mieć krótszy kod, w którym mógłbym bezpośrednio dodać „cel”.

AdN14
źródło
0

Interfejs API jest nieco bardziej przejrzysty niż sugerowane odpowiedzi. Tutaj, używając as_framei pamiętaj, aby dołączyć również kolumnę odpowiedzi.

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)
Nauka statystyk na przykładzie
źródło
0

Oto inny przykład zintegrowanej metody.

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)

Dane iris_X są importowane jako pandy DataFrame, a docelowe iris_y są importowane jako pandy Series.

Joe
źródło
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()
Ankit Mathanker
źródło
0

To łatwa metoda zadziałała dla mnie.

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

Ale można to również zastosować do load_iris.

user3151256
źródło