57

我有一个大数据集,想把它分成训练集(50%)和测试集(50%)。

假设我有 100 个示例存储了输入文件,每一行包含一个示例。我需要选择 50 行作为训练集和 50 行测试集。

我的想法是首先生成一个长度为 100 的随机列表(值范围从 1 到 100),然后使用前 50 个元素作为 50 个训练示例的行号。与测试集相同。

这可以在 Matlab 中轻松实现

fid=fopen(datafile);
C = textscan(fid, '%s','delimiter', '\n');
plist=randperm(100);
for i=1:50
    trainstring = C{plist(i)};
    fprintf(train_file,trainstring);
end
for i=51:100
    teststring = C{plist(i)};
    fprintf(test_file,teststring);
end

但是我怎么能在 Python 中完成这个功能呢?我是 Python 新手,不知道我是否可以将整个文件读入一个数组,然后选择某些行。

4

9 回答 9

94

这可以在 Python 中使用列表类似地完成(请注意,整个列表都被打乱了)。

import random

with open("datafile.txt", "rb") as f:
    data = f.read().split('\n')

random.shuffle(data)

train_data = data[:50]
test_data = data[50:]
于 2013-07-01T20:44:15.190 回答
33
from sklearn.model_selection import train_test_split
import numpy

with open("datafile.txt", "rb") as f:
   data = f.read().split('\n')
   data = numpy.array(data)  #convert array to numpy type array

   x_train ,x_test = train_test_split(data,test_size=0.5)       #test_size=0.5(whole_data)
于 2017-01-24T09:24:38.213 回答
14

为了回答@desmond.carros 的问题,我将最佳答案修改如下,

 import random
 file=open("datafile.txt","r")
 data=list()
 for line in file:
    data.append(line.split(#your preferred delimiter))
 file.close()
 random.shuffle(data)
 train_data = data[:int((len(data)+1)*.80)] #Remaining 80% to training set
 test_data = data[int((len(data)+1)*.80):] #Splits 20% data to test set

该代码将整个数据集拆分为 80% 的训练数据和 20% 的测试数据

于 2017-02-02T03:55:14.853 回答
9

你也可以使用 numpy. 当您的数据存储在 numpy.ndarray 中时:

import numpy as np
from random import sample
l = 100 #length of data 
f = 50  #number of elements you need
indices = sample(range(l),f)

train_data = data[indices]
test_data = np.delete(data,indices)
于 2016-05-06T09:45:43.603 回答
6

你可以试试这个方法

import pandas
import sklearn
csv = pandas.read_csv('data.csv')
train, test = sklearn.cross_validation.train_test_split(csv, train_size = 0.5)

更新train_test_split已移至model_selection当前的执行方式(scikit-learn 0.22.2)是这样的:

import pandas
import sklearn
csv = pandas.read_csv('data.csv')
train, test = sklearn.model_selection.train_test_split(csv, train_size = 0.5)
于 2016-09-04T16:19:45.057 回答
6

sklearn.cross_validation自 0.18 版起已弃用,您应该使用sklearn.model_selection如下所示

from sklearn.model_selection import train_test_split
import numpy

with open("datafile.txt", "rb") as f:
   data = f.read().split('\n')
   data = numpy.array(data)  #convert array to numpy type array

   x_train ,x_test = train_test_split(data,test_size=0.5)       #test_size=0.5(whole_data)
于 2017-10-18T01:04:26.913 回答
3

以下产生更一般的 k 折交叉验证拆分。您的 50-50 分区将通过k=2以下方式实现,您所要做的就是选择生成的两个分区之一。注意:我还没有测试过代码,但我很确定它应该可以工作。

import random, math

def k_fold(myfile, myseed=11109, k=3):
    # Load data
    data = open(myfile).readlines()

    # Shuffle input
    random.seed=myseed
    random.shuffle(data)

    # Compute partition size given input k
    len_part=int(math.ceil(len(data)/float(k)))

    # Create one partition per fold
    train={}
    test={}
    for ii in range(k):
        test[ii]  = data[ii*len_part:ii*len_part+len_part]
        train[ii] = [jj for jj in data if jj not in test[ii]]

    return train, test      
于 2014-06-25T19:50:10.093 回答
0

来自@subin sahayam 答案的快速说明

 import random
 file=open("datafile.txt","r")
 data=list()
 for line in file:
    data.append(line.split(#your preferred delimiter))
 file.close()
 random.shuffle(data)
 train_data = data[:int((len(data)+1)*.80)] #Remaining 80% to training set
 test_data = data[int(len(data)*.80+1):] #Splits 20% data to test set

如果您的列表大小是偶数,则不应在下面的代码中添加 1。相反,您需要先检查列表的大小,然后确定是否需要添加 1。

test_data = data[int(len(data)*.80+1):]

于 2018-07-24T14:44:09.960 回答
-2

首先,Python 中没有“数组”之类的东西,Python 使用列表,这确实会产生影响,我建议你使用NumPy,它是 Python 的一个非常好的库,它添加了很多类似 Matlab 的功能。你可以从这里开始Numpy for Matlab 用户

于 2013-07-01T20:03:52.947 回答