如何随机将数据拆分为trainset和testset?

时间:2013-07-01 19:44:34

标签: python file-io

我有一个大型数据集,并希望将其拆分为培训(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的新手,不知道我是否可以将整个文件读入数组,并选择某些行。

9 个答案:

答案 0 :(得分:59)

这可以通过使用列表在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:]

答案 1 :(得分:19)

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)

答案 2 :(得分:7)

你也可以使用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)

答案 3 :(得分:6)

自版本0.18起,

sklearn.cross_validation已弃用,您应使用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)

答案 4 :(得分:5)

要回答@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)*.80+1):] #Splits 20% data to test set

代码将整个数据集拆分为80%的列车和20%的测试数据

答案 5 :(得分:2)

以下产生更一般的k-fold交叉验证分裂。您可以通过下面的k=2来实现50-50分区,您只需要选择生成的两个分区中的一个。注意:我还没有对代码进行测试,但我确信它应该有效。

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      

答案 6 :(得分:2)

您可以尝试这种方法

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

答案 7 :(得分:0)

首先,没有"数组"在Python中,Python使用列表并确实有所不同,我建议你使用 NumPy 这是一个非常好的Python库,它增加了许多类似Matlab的功能。你可以在这里开始{ {3}}

答案 8 :(得分: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(len)*。80 + 1):]