मैं पंडों के साथ एक डेटाफ्रेम से परीक्षण और ट्रेन नमूने कैसे बना सकता हूं?


322

मेरे पास डेटाफ़्रेम के रूप में एक बहुत बड़ा डेटासेट है और मैं सोच रहा था कि मैं प्रशिक्षण और परीक्षण के लिए डेटाफ़्रेम को दो यादृच्छिक नमूनों (80% और 20%) में कैसे विभाजित कर पाऊंगा।

धन्यवाद!

जवाबों:


346

मैं सिर्फ numpy का उपयोग करूंगा randn:

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]

और बस यह देखने के लिए काम किया है:

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

In [16]: len(train)
Out[16]: 79

3
माफ कीजिएगा यह मेरी गलती है। लंबे समय के रूप के रूप में mskdtype की है bool, df[msk], df.iloc[msk]और df.loc[msk]हमेशा एक ही परिणाम लौटने।
अनटुब

2
मुझे लगता है कि आपको समझ बनाने के randलिए उपयोग करना चाहिए < 0.8क्योंकि यह 0 और 1. के बीच समान रूप से वितरित यादृच्छिक संख्या देता है
आर मैक्स

4
किसी अजगर शर्तों वास्तव में लाइनों में होता है क्या में विशुद्ध रूप से व्याख्या कर सकते हैं in[12], in[13], in[14]? मैं यहाँ अजगर कोड को समझना चाहता हूँ
kuatroka

7
Gobrewers14 से स्केलेर का उपयोग करने का उत्तर बेहतर है। यह कम जटिल है और डिबग करना आसान है। मैं नीचे दिए गए उत्तर का उपयोग करने की सलाह देता हूं।
तो 15

2
@kuatroka श्रेणी [0, 1] में बेतरतीब ढंग से और समान रूप से वितरित फ्लोट मूल्यों के साथ np.random.rand(len(df))आकार की एक सरणी है len(df)< 0.8तुलना तत्व के लिहाज से और दुकानों जगह में परिणाम लागू होता है। इस प्रकार मान <0.8 बन जाते हैं Trueऔर मूल्य> = 0.8 बन जाते हैंFalse
केंटजो

623

scikit सीखनाtrain_test_split एक अच्छा है।

from sklearn.model_selection import train_test_split

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

22
यह सुन्न सरणियों को लौटाएगा न कि पंडों डेटाफ़्रेम को
बार

124
Btw, यह अब एक पंडस डेटाफ़्रेम लौटाता है (सिर्फ स्केलेरन 0.16.1 पर परीक्षण किया गया)
जुलिएन मार्रेक

5
यदि आप KFold की तलाश कर रहे हैं, तो यह थोड़ा और अधिक जटिल है। kf = KFold(n, n_folds=folds) for train_index, test_index in kf: X_train, X_test = X.ix[train_index], X.ix[test_index]पूरा उदाहरण यहां देखें: quantstart.com/articles/…
ihadanny

12
नए संस्करणों में (0.18, शायद पहले), from sklearn.model_selection import train_test_splitइसके बजाय आयात करें ।
मार्क

7
नवीनतम SciKit संस्करण में आपको इसे अभी कॉल करने की आवश्यकता है:from sklearn.cross_validation import train_test_split
horseshoe

289

पंडों यादृच्छिक नमूना भी काम करेगा

train=df.sample(frac=0.8,random_state=200) #random state is a seed value
test=df.drop(train.index)

.Index का क्या अर्थ है / DataFrame पर .index के लिए प्रलेखन कहां है? मैं इसे नहीं ढूँढ सकता।
16

1
random_stateआर्ग क्या कर रहा है?
ऋषभ अग्रहरी

1
@ ऋषभअघारी बेतरतीब ढंग से फ़्रेग आर्ग के अनुसार हर बार अलग-अलग डेटा को अलग करता है। यदि आप यादृच्छिकता को नियंत्रित करना चाहते हैं तो आप अपने स्वयं के बीज को उदाहरण में बता सकते हैं।
माइकेल

4
यह स्केलेरन में लाने की तुलना में अच्छी तरह से और अधिक सुरुचिपूर्ण समाधान काम करता है। क्या कोई कारण है कि यह एक बेहतर स्वीकृत उत्तर नहीं होना चाहिए?
राजवी

1
@peer कि सीमा को आसानी से हटा दिया जाता है अगर एक फेरबदल testसेट वांछित है जैसा कि यहां बताया गया है stackoverflow.com/questions/29576430/shuffle-dataframe-rowstest=df.drop(train.index).sample(frac=1.0)
आलोक लाल

32

मैं scikit- लर्निंग के अपने प्रशिक्षण_test_split का उपयोग करता हूं, और इसे सूचकांक से उत्पन्न करता हूं

from sklearn.model_selection 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

3
cross_validationमॉड्यूल अब पदावनत किया गया है:DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
हैरी

19

ट्रेन / परीक्षण और यहां तक ​​कि सत्यापन के नमूने बनाने के कई तरीके हैं।

केस 1: train_test_splitबिना किसी विकल्प के क्लासिक तरीका :

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

केस 2: एक बहुत छोटे डेटासेट का मामला (<500 पंक्तियाँ): इस क्रॉस-वैलिडेशन के साथ आपकी सभी लाइनों के लिए परिणाम प्राप्त करने के लिए। अंत में, आपके पास अपने उपलब्ध प्रशिक्षण सेट की प्रत्येक पंक्ति के लिए एक भविष्यवाणी होगी।

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)

केस 3 ए: वर्गीकरण उद्देश्य के लिए असंतुलित डेटासेट। मामले 1 के बाद, यहाँ बराबर समाधान है:

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)

केस 3 बी: वर्गीकरण उद्देश्य के लिए असंतुलित डेटासेट। मामले 2 के बाद, यहाँ बराबर समाधान है:

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)

केस 4: आपको हाइपरपैरमीटर (60% ट्रेन, 20% परीक्षण और 20% वैल) को ट्यून करने के लिए बड़े डेटा पर एक ट्रेन / टेस्ट / सत्यापन सेट बनाने की आवश्यकता है।

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)

13

परीक्षण और ट्रेन नमूने बनाने के लिए आप नीचे दिए गए कोड का उपयोग कर सकते हैं:

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

आपके आकार को आपके परीक्षण और ट्रेन डेटासेट में रखने के प्रतिशत के आधार पर परीक्षण का आकार भिन्न हो सकता है।


7

कई मान्य उत्तर हैं। गुच्छा में एक और जोड़ना। sklearn.cross_validation आयात ट्रेन_टेस्ट_स्प्लिट से

#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)]

5

आप प्रशिक्षण और परीक्षण सेट में स्तरीकृत विभाजन पर भी विचार कर सकते हैं। प्रारंभ डिवीजन भी यादृच्छिक रूप से प्रशिक्षण और परीक्षण सेट उत्पन्न करता है लेकिन इस तरह से कि मूल वर्ग अनुपात संरक्षित हैं। यह प्रशिक्षण और परीक्षण सेट को मूल डेटासेट के गुणों को बेहतर ढंग से दर्शाता है।

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

df [train_inds] और df [test_inds] आपको अपने मूल DataFrame df का प्रशिक्षण और परीक्षण सेट प्रदान करते हैं।


पर्यवेक्षित शिक्षण कार्यों के लिए यह बेहतर रणनीति है।
विन्सेन्टमजोर

इसका उपयोग करने की कोशिश करते समय मुझे एक त्रुटि मिल रही है। ValueError: असाइनमेंट डेस्टिनेशन केवल "np.random.shuffle (value_inds)" लाइन में पढ़ा जाता है
Markus W

4

यदि आपको अपने डेटा सेट के संबंध में अपने डेटा को विभाजित करने की आवश्यकता है तो आप इसका उपयोग कर सकते हैं:

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

और इसका उपयोग करें:

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

यदि आप विभाजन यादृच्छिकता को नियंत्रित करना चाहते हैं या कुछ वैश्विक यादृच्छिक बीज का उपयोग करना चाहते हैं, तो आप random_state भी पास कर सकते हैं।


3
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
आपसे थोड़ी गलती हुई है। इससे पहले कि आप लक्ष्य स्तंभ छोड़ें, आप उसे train_test_split में डाल दें। data = data.drop (कॉलम = ['column_name'], अक्ष = 1)
Anton Erjomin

3

आप df.sample () का उपयोग करके मापी गई पंक्तियों को बाहर करने के लिए ~ (tilde ऑपरेटर) का उपयोग कर सकते हैं, दो सेट प्राप्त करने के लिए पंडों को अकेले ही नमूने के नमूने और फ़िल्टरिंग को संभालने देते हैं।

train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]

2

यह वही है जो मैंने लिखा था जब मुझे एक DataFrame को विभाजित करने की आवश्यकता थी। मैंने ऊपर एंडी के दृष्टिकोण का उपयोग करने पर विचार किया, लेकिन यह पसंद नहीं था कि मैं डेटा सेट के आकार को बिल्कुल नियंत्रित नहीं कर सकता (यानी, यह कभी-कभी 79, कभी-कभी 81, आदि होगा)।

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

बस इस तरह से df से रेंज रो का चयन करें

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

3
यह तभी काम करेगा जब डेटाफ्रेम में डेटा पहले से ही बेतरतीब ढंग से ऑर्डर किया गया हो। यदि डेटासेट अल्ट्रस स्रोतों से प्राप्त होता है और उसी डेटाफ्रेम में जोड़ा गया है, तो उपरोक्त का उपयोग करके प्रशिक्षण / परीक्षण के लिए एक बहुत तिरछा डेटासेट प्राप्त करना काफी संभव है।
एमिल एच

1
आप dataframe शफ़ल कर सकते हैं विभाजन से पहले ही stackoverflow.com/questions/29576430/shuffle-dataframe-rows
माकिओ

1
Absolutelty! यदि आप जोड़ते हैं कि dfआपके कोड में स्निपेट (या होना चाहिए) फेरबदल किया गया है तो इससे उत्तर में सुधार होगा।
एमिल एच

2

ऊपर कई शानदार जवाब हैं इसलिए मैं सिर्फ एक और उदाहरण जोड़ना चाहता हूं कि आप सिर्फ numpyलाइब्रेरी का उपयोग करके ट्रेन और परीक्षण सेट के लिए नमूनों की सटीक संख्या निर्दिष्ट करना चाहते हैं ।

# set the random seed for the reproducibility
np.random.seed(17)

# e.g. number of samples for the training set is 1000
n_train = 1000

# shuffle the indexes
shuffled_indexes = np.arange(len(data_df))
np.random.shuffle(shuffled_indexes)

# use 'n_train' samples for training and the rest for testing
train_ids = shuffled_indexes[:n_train]
test_ids = shuffled_indexes[n_train:]

train_data = data_df.iloc[train_ids]
train_labels = labels_df.iloc[train_ids]

test_data = data_df.iloc[test_ids]
test_labels = data_df.iloc[test_ids]

2

ट्रेन, परीक्षण और सत्यापन जैसे दो से अधिक वर्गों में विभाजित करने के लिए, कोई भी कर सकता है:

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]

यह प्रशिक्षण में लगभग 70% डेटा, परीक्षण में 15% और सत्यापन में 15% डाल देगा।


1
आप "लगभग" जोड़ने के लिए अपने उत्तर को संपादित करना चाह सकते हैं, यदि आप कोड चलाते हैं तो आप देखेंगे कि यह सटीक प्रतिशत से काफी दूर हो सकता है। उदाहरण के लिए मैंने इसे 1000 वस्तुओं पर आज़माया और मिला: 700, 141, 159 - इसलिए 70%, 14% और 16%।
स्टेसन

2

आपको पांडा डेटाफ़्रेम को सुपीरियर एरे में बदलना होगा और फिर क्रिस्पी एरे को वापस डेटाफ़्रेम में बदलना होगा

 import pandas as pd
df=pd.read_csv('/content/drive/My Drive/snippet.csv', sep='\t')
from sklearn.model_selection import train_test_split

train, test = train_test_split(df, test_size=0.2)
train1=pd.DataFrame(train)
test1=pd.DataFrame(test)
train1.to_csv('/content/drive/My Drive/train.csv',sep="\t",header=None, encoding='utf-8', index = False)
test1.to_csv('/content/drive/My Drive/test.csv',sep="\t",header=None, encoding='utf-8', index = False)

स्टैक ओवरफ्लो पर कोड-केवल उत्तर स्वीकार्य नहीं हैं।
VFDan

1

यदि आपकी इच्छा एक डेटाफ्रेम और दो डेटाफ्रेम आउट करने की है (सुन्न सरणियों की नहीं), तो यह चाल चलनी चाहिए:

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

1

आप df.as_matrix () फ़ंक्शन का उपयोग कर सकते हैं और Numpy-array बना सकते हैं और इसे पास कर सकते हैं।

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

मेरे स्वाद के लिए थोड़ा अधिक सुरुचिपूर्ण एक यादृच्छिक स्तंभ बनाना है और फिर इसके द्वारा विभाजित करना है, इस तरह हम एक विभाजन प्राप्त कर सकते हैं जो हमारी आवश्यकताओं के अनुरूप होगा और यादृच्छिक होगा।

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

मुझे लगता है कि यदि आप बाद में कॉलम जोड़ना चाहते हैं तो आपको एक कॉपी भी प्राप्त करने की आवश्यकता नहीं है।

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

0

इस बारे में कैसा है? df मेरी डेटाफ्रेम है

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

सुन्न में बदलने की जरूरत नहीं है। विभाजन करने के लिए बस एक पांडा डीएफ का उपयोग करें और यह एक पांडा डीएफ लौटाएगा।

from sklearn.model_selection import train_test_split

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

0
shuffle = np.random.permutation(len(df))
test_size = int(len(df) * 0.2)
test_aux = shuffle[:test_size]
train_aux = shuffle[test_size:]
TRAIN_DF =df.iloc[train_aux]
TEST_DF = df.iloc[test_aux]

2
यह एक बेहतर उत्तर होगा यदि आपने बताया कि आपने जिस कोड को प्रदान किया है वह प्रश्न का उत्तर कैसे देता है।
पपड़ी

हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन यह समस्या का हल कैसे और / या इसके बारे में अतिरिक्त संदर्भ प्रदान करता है, इससे उत्तर के दीर्घकालिक मूल्य में सुधार होगा।
शौनकडे

पहली पंक्ति एक फेरबदल सीमा (डेटाफ़्रेम के आकार के संबंध में) लौटाती है। दूसरी पंक्ति परीक्षण सेट के वांछित अंश का प्रतिनिधित्व करती है। तीसरी और अगली पंक्ति अंश को फेरबदल सीमा में शामिल करती है। बाकी पंक्तियाँ स्वयं व्याख्यात्मक होनी चाहिए ।सादर।
एलीट डी जनरल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.