如何使用pandas从一个数据框创建测试和训练样本?

too*_*y44 268 python dataframe python-2.7 pandas

我有一个相当大的数据集形式的数据集,我想知道如何将数据帧分成两个随机样本(80%和20%)进行训练和测试.

谢谢!

gob*_*s14 544

scikit learntrain_test_split是一个很好的.

from sklearn.model_selection import train_test_split

train, test = train_test_split(df, test_size=0.2)
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一句,它确实现在返回一个Pandas Dataframe(刚刚在Sklearn 0.16.1上测试过) (100认同)
  • 这将返回numpy数组,而不是Pandas Dataframes (17认同)
  • 在新版本(0.18,可能更早)中,导入为来自sklearn.model_selection import train_test_split`. (12认同)
  • 在最新的SciKit版本中,您需要将其称为:`from sklearn.cross_validation import train_test_split` (7认同)
  • 如果你正在寻找KFold,它可能会更加复杂.`kf = kFold(n,n_folds = folds)用于train_index,test_index用于kf:X_train,X_test = X.ix [train_index],X.ix [test_index]`在此处查看完整示例:https://www.quantstart.com /用品/使用交叉验证,对优化-A-机器学习方法的回归设定 (5认同)
  • @horseshoe不推荐使用cv模块:`DeprecationWarning:这个模块在版本0.18中已被弃用,而不是所有重构的类和函数都被移动到的model_selection模块.另请注意,新CV迭代器的接口与此模块的接口不同.该模块将在0.20中删除."这个模块将在0.20中删除.",DeprecationWarning)` (5认同)

And*_*den 303

我会用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]
Run Code Online (Sandbox Code Playgroud)

只是为了看到这个有效:

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

In [16]: len(train)
Out[16]: 79
Run Code Online (Sandbox Code Playgroud)

  • 使用来自*gobrewers14*的**sklearn**的答案是更好的答案.它不那么复杂,也更容易调试.我建议使用下面的答案. (6认同)
  • 有人可以纯粹用python术语解释在[12]`中的行`,[13]`,`[14]中的行中究竟发生了什么?我想在这里理解python代码本身 (3认同)
  • 抱歉,是我的错.只要`msk`是dtype`bool`,`df [msk]`,`df.iloc [msk]`和`df.loc [msk]`总是返回相同的结果. (2认同)
  • 我认为你应该使用`rand`到`<0.8`才有意义,因为它返回0到1之间均匀分布的随机数. (2认同)
  • `np.random.rand(N)` 创建一个 0 到 1 之间的随机浮点数的 numpy 数组,因此值是否 &lt; 0.8 将它们分类为 80% 和 20%。~ 是反转运算符(因此 True 变为 False,False 变为 True 布尔值),df[booleans] 过滤 DataFrame 以仅具有真值。 (2认同)
  • @kuatroka`np.random.rand(len(df))`是一个大小为"len(df)"的数组,在[0,1]范围内随机且均匀分布的浮点值.`<0.8`应用比较元素并将结果存储到位.因此,值<0.8变为"真"并且值> = 0.8变为"假" (2认同)

Pag*_*Max 251

熊猫随机样本也会起作用

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

  • 这似乎运作良好,并且是比引入 sklearn 更优雅的解决方案。有没有理由认为这不应该是一个更好接受的答案? (8认同)
  • @RajV 当前形式的“test”将被随机选择,但行将按其原始顺序排列。sklearn 方法对训练和测试进行了调整。 (3认同)
  • @peer,如果需要一个随机的“测试”集,那么限制很容易解决,如此处指出的/sf/ask/2070350131/。`test=df.drop(train.index).sample(frac=1.0)` (3认同)
  • `random_state` arg 正在做什么? (2认同)
  • @RishabhAgrahari 每次根据 frac arg 随机洗牌不同的数据分割。如果您想控制随机性,您可以声明自己的种子,如示例中所示。 (2认同)

Nap*_*Jon 26

我会使用scikit-learn自己的training_test_split,并从索引中生成它

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
Run Code Online (Sandbox Code Playgroud)

  • 现在不推荐使用`cross_validation`模块:`DeprecationWarning:在0.18版本中不推荐使用此模块,而是支持所有重构的类和函数都移动到的model_selection模块.另请注意,新CV迭代器的接口与此模块的接口不同.该模块将在0.20中删除 (2认同)
  • 使用sklearn.model_selection import train_test_split (2认同)

Nos*_*sey 18

无需转换为 numpy。只需使用pandas df 进行拆分,它将返回一个pandas df。

from sklearn.model_selection import train_test_split

train, test = train_test_split(df, test_size=0.2)
Run Code Online (Sandbox Code Playgroud)

如果你想从 y 中拆分 x

X_train, X_test, y_train, y_test = train_test_split(df[list_of_x_cols], df[y_col],test_size=0.2)

Run Code Online (Sandbox Code Playgroud)

如果你想拆分整个 df

X, y = df[list_of_x_cols], df[y_col]
Run Code Online (Sandbox Code Playgroud)


小智 12

您可以使用以下代码创建测试和训练样本:

from sklearn.model_selection import train_test_split
trainingSet, testSet = train_test_split(df, test_size=0.2)
Run Code Online (Sandbox Code Playgroud)

测试大小可能会根据您要在测试和训练数据集中放入的数据百分比而有所不同.


小智 9

创建训练/测试甚至验证样本的方法有很多。

情况1:train_test_split没有任何选择的经典方式:

from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.3)
Run Code Online (Sandbox Code Playgroud)

情况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)
Run Code Online (Sandbox Code Playgroud)

情况3a:用于分类目的的不平衡数据集。在第一种情况之后,这里是等效的解决方案:

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)
Run Code Online (Sandbox Code Playgroud)

情况3b:出于分类目的的不平衡数据集。在案例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)
Run Code Online (Sandbox Code Playgroud)

案例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)
Run Code Online (Sandbox Code Playgroud)


Abh*_*bhi 7

有许多有效的答案.再添一个.来自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)]
Run Code Online (Sandbox Code Playgroud)


Apo*_*tus 5

您也可以考虑将分层划分为训练和测试集.Startized division还会随机生成训练和测试集,但这样可以保留原始的比例.这使得训练和测试集更好地反映了原始数据集的属性.

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
Run Code Online (Sandbox Code Playgroud)

df [train_inds]和df [test_inds]为您提供原始DataFrame df的训练和测试集.


Mak*_*kio 5

只需从 df 中选择范围行,如下所示

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

  • 仅当数据框中的数据已经随机排序时,这才有效。如果数据集源自多个源并已附加到同一数据帧,那么很可能会使用上述方法获得一个非常倾斜的数据集用于训练/测试。 (3认同)

Mik*_*keL 5

如果您需要根据数据集中的标签列拆分数据,您可以使用以下命令:

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
Run Code Online (Sandbox Code Playgroud)

并使用它:

train, test = split_to_train_test(data, 'class', 0.7)
Run Code Online (Sandbox Code Playgroud)

如果你想控制分裂随机性或使用一些全局随机种子,你也可以传递 random_state 。


小智 5

您可以使用 ~ (波浪号运算符)排除使用 df.sample() 采样的行,让熊猫单独处理索引的采样和过滤,以获得两组。

train_df = df.sample(frac=0.8, random_state=100)
test_df = df[~df.index.isin(train_df.index)]
Run Code Online (Sandbox Code Playgroud)