it-swarm.com.de

Wie erstelle ich mit Pandas Test- und Trainingsbeispiele aus einem Datenrahmen?

Ich habe einen ziemlich großen Datensatz in Form eines Datenrahmens und ich habe mich gefragt, wie ich den Datenrahmen in zwei Stichproben (80% und 20%) für das Training und Testen aufteilen könnte.

Vielen Dank!

211
tooty44

Ich würde nur Numpys randn verwenden:

In [11]: df = pd.DataFrame(np.random.randn(100, 2))

In [12]: msk = np.random.Rand(len(df)) < 0.8

In [13]: train = df[msk]

In [14]: test = df[~msk]

Und nur zu sehen, dass dies funktioniert hat:

In [15]: len(test)
Out[15]: 21

In [16]: len(train)
Out[16]: 79
236
Andy Hayden

scikit lernens train_test_split ist ein guter.

from sklearn.model_selection import train_test_split

train, test = train_test_split(df, test_size=0.2)
430
gobrewers14

Pandas Zufallsstichprobe funktioniert auch 

train=df.sample(frac=0.8,random_state=200)
test=df.drop(train.index)
198
PagMax

Ich würde scikit-learns eigenes training_test_split verwenden und es aus dem Index generieren

from sklearn.cross_validation import train_test_split


y = df.pop('output')
X = df

X_train,X_test,y_train,y_test = train_test_split(X.index,y,test_size=0.2)
X.iloc[X_train] # return dataframe train
24
Napitupulu Jon

Sie können den folgenden Code verwenden, um Test- und Trainingsbeispiele zu erstellen:

from sklearn.model_selection import train_test_split
trainingSet, testSet = train_test_split(df, test_size=0.2)

Die Testgröße kann je nach dem Prozentsatz der Daten variieren, die Sie in Ihr Test- und Trainings-Dataset einfügen möchten.

11
user1775015

Es gibt viele gültige Antworten. Hinzufügen eines weiteren zum Bündel . Aus sklearn.cross_validation import train_test_split

#gets a random 80% of the entire set
X_train = X.sample(frac=0.8, random_state=1)
#gets the left out portion of the dataset
X_test = X.loc[~df_model.index.isin(X_train.index)]
6
Abhi

Sie können auch eine stratifizierte Einteilung in Schulungs- und Testset in Betracht ziehen. Startified Division generiert auch Trainings- und Test-Sets nach dem Zufallsprinzip, jedoch so, dass die ursprünglichen Klassenverhältnisse erhalten bleiben. Dadurch können Schulungs- und Testsätze die Eigenschaften des ursprünglichen Datensatzes besser widerspiegeln.

import numpy as np  

def get_train_test_inds(y,train_proportion=0.7):
    '''Generates indices, making random stratified split into training set and testing sets
    with proportions train_proportion and (1-train_proportion) of initial sample.
    y is any iterable indicating classes of each observation in the sample.
    Initial proportions of classes inside training and 
    testing sets are preserved (stratified sampling).
    '''

    y=np.array(y)
    train_inds = np.zeros(len(y),dtype=bool)
    test_inds = np.zeros(len(y),dtype=bool)
    values = np.unique(y)
    for value in values:
        value_inds = np.nonzero(y==value)[0]
        np.random.shuffle(value_inds)
        n = int(train_proportion*len(value_inds))

        train_inds[value_inds[:n]]=True
        test_inds[value_inds[n:]]=True

    return train_inds,test_inds

mit df [train_inds] und df [test_inds] erhalten Sie die Schulungs- und Testsätze Ihres ursprünglichen DataFrame-df.

5
Apogentus

Wenn Sie Ihre Daten in Bezug auf die Spalte "Lables" in Ihrem Datensatz aufteilen müssen, können Sie Folgendes verwenden:

def split_to_train_test(df, label_column, train_frac=0.8):
    train_df, test_df = pd.DataFrame(), pd.DataFrame()
    labels = df[label_column].unique()
    for lbl in labels:
        lbl_df = df[df[label_column] == lbl]
        lbl_train_df = lbl_df.sample(frac=train_frac)
        lbl_test_df = lbl_df.drop(lbl_train_df.index)
        print '\n%s:\n---------\ntotal:%d\ntrain_df:%d\ntest_df:%d' % (lbl, len(lbl_df), len(lbl_train_df), len(lbl_test_df))
        train_df = train_df.append(lbl_train_df)
        test_df = test_df.append(lbl_test_df)

    return train_df, test_df

und benutze es:

train, test = split_to_train_test(data, 'class', 0.7)

sie können auch random_state übergeben, wenn Sie die Split-Zufälligkeit steuern oder einen globalen Zufallsstart verwenden möchten.

2
MikeL

Das habe ich geschrieben, als ich einen DataFrame aufteilen musste. Ich habe darüber nachgedacht, den Ansatz von Andys zu verwenden, aber mir gefiel es nicht, dass ich die Größe der Datensätze nicht genau kontrollieren konnte (d. H. Es würde manchmal 79, manchmal 81 usw. sein).

def make_sets(data_df, test_portion):
    import random as rnd

    tot_ix = range(len(data_df))
    test_ix = sort(rnd.sample(tot_ix, int(test_portion * len(data_df))))
    train_ix = list(set(tot_ix) ^ set(test_ix))

    test_df = data_df.ix[test_ix]
    train_df = data_df.ix[train_ix]

    return train_df, test_df


train_df, test_df = make_sets(data_df, 0.2)
test_df.head()
2
Anarcho-Chossid
import pandas as pd

from sklearn.model_selection import train_test_split

datafile_name = 'path_to_data_file'

data = pd.read_csv(datafile_name)

target_attribute = data['column_name']

X_train, X_test, y_train, y_test = train_test_split(data, target_attribute, test_size=0.8)
2
Pardhu Gopalam

Um in mehr als zwei Klassen aufzuteilen, wie Zug, Test und Validierung, kann man Folgendes tun:

probs = np.random.Rand(len(df))
training_mask = probs < 0.7
test_mask = (probs>=0.7) & (probs < 0.85)
validatoin_mask = probs >= 0.85


df_training = df[training_mask]
df_test = df[test_mask]
df_validation = df[validatoin_mask]

Dies bedeutet, dass 70% der Daten im Training, 15% im Test und 15% in der Validierung enthalten sind.

1
AHonarmand

Wählen Sie einfach die Bereichszeile aus df aus

row_count = df.shape[0]
split_point = int(row_count*1/5)
test_data, train_data = df[:split_point], df[split_point:]
1
Makio

Es gibt viele Möglichkeiten, Zug-/Test- und sogar Validierungsmuster zu erstellen.

Fall 1: klassischer Weg train_test_split ohne Optionen:

from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)

Fall 2: Fall eines sehr kleinen Datensatzes (<500 Zeilen): um Ergebnisse für alle Ihre Zeilen mit dieser Kreuzvalidierung zu erhalten. Am Ende haben Sie eine Vorhersage für jede Zeile Ihres verfügbaren Trainingssatzes.

from sklearn.model_selection import KFold
kf = KFold(n_splits=10, random_state=0)
y_hat_all = []
for train_index, test_index in kf.split(X, y):
    reg = RandomForestRegressor(n_estimators=50, random_state=0)
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf = reg.fit(X_train, y_train)
    y_hat = clf.predict(X_test)
    y_hat_all.append(y_hat)

Fall 3a: Unsymmetrische Datensätze zur Klassifizierung. Nach dem Fall 1 ist hier die äquivalente Lösung:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.3)

Fall 3b: Unsymmetrische Datensätze für Klassifizierungszwecke. Nach dem Fall 2 ist hier die äquivalente Lösung:

from sklearn.model_selection import StratifiedKFold
kf = StratifiedKFold(n_splits=10, random_state=0)
y_hat_all = []
for train_index, test_index in kf.split(X, y):
    reg = RandomForestRegressor(n_estimators=50, random_state=0)
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf = reg.fit(X_train, y_train)
    y_hat = clf.predict(X_test)
    y_hat_all.append(y_hat)

Fall 4: Sie müssen einen Zug/Test/Validierungssatz für Big Data erstellen, um die Hyperparameter zu optimieren (60% Zug, 20% Test und 20% Wert).

from sklearn.model_selection import train_test_split
X_train, X_test_val, y_train, y_test_val = train_test_split(X, y, test_size=0.6)
X_test, X_val, y_test, y_val = train_test_split(X_test_val, y_test_val, stratify=y, test_size=0.5)
1
yannick_leo

Sie können die Funktion df.as_matrix () verwenden und ein Numpy-Array erstellen und übergeben.

Y = df.pop()
X = df.as_matrix()
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size = 0.2)
model.fit(x_train, y_train)
model.test(x_test)
1
kiran6

Ich denke, Sie müssen auch eine Kopie erhalten, nicht ein Stück Dataframe, wenn Sie später Spalten hinzufügen möchten.

msk = np.random.Rand(len(df)) < 0.8
train, test = df[msk].copy(deep = True), df[~msk].copy(deep = True)
0
Hakim

Wie wäre es damit? Df ist mein Datenrahmen

total_size=len(df)

train_size=math.floor(0.66*total_size) (2/3 part of my dataset)

#training dataset
train=df.head(train_size)
#test dataset
test=df.tail(len(df) -train_size)
0
Akash Jain

Wenn Sie einen Datenrahmen und zwei Datenrahmen (keine numpy-Arrays) wünschen, sollten Sie dies tun:

def split_data(df, train_perc = 0.8):

   df['train'] = np.random.Rand(len(df)) < train_perc

   train = df[df.train == 1]

   test = df[df.train == 0]

   split_data ={'train': train, 'test': test}

   return split_data
0
Johnny V

Etwas eleganter für meinen Geschmack ist es, eine zufällige Kolumne zu erstellen und diese danach aufzuteilen. Auf diese Weise können wir einen Split erhalten, der unseren Bedürfnissen entspricht und zufällig ist. 

def split_df(df, p=[0.8, 0.2]):
import numpy as np
df["Rand"]=np.random.choice(len(p), len(df), p=p)
r = [df[df["Rand"]==val] for val in df["Rand"].unique()]
return r
0
thebeancounter