从大文件中随机抽取一定数据

在建模的时候,时常需要构造训练集和测试集,但当总数据比较大的时候,如何进行简单抽样也是一个问题。

假设有这样一个情况,一份数据总共有1,000,000条,要从中抽取100,000条左右的数据。每条数据相对比较大,把所有数据一次放入内存不靠谱,那么如何抽样呢?

最龊的方法就是抽取头100,000或100,000条。

第二种能想到的方法就是,构造一个1-1,000,000的数组,然后从里面随机抽取100,000个作为样本行号列表,在读取大文件,一旦行号在列表中就输出到样本文件中。

第二种方法基本够用,但还是存在一定缺陷。当总数据非常大,需要抽取的样本数也不小时,或机器内存较小时。于是考虑到使用概率方式,在[1-n]作均匀随机抽取数字,那么期望值(n+1)/2,也就是说随机足够多次数,那么所有的随机出来的数字的平均数为(n+1)/2。那么是否可以这样考虑,我们每随机一个值a,就把大文件中中连续的a行作为一个块,那么最后每个块的平均大小为(n+1)/2,也就是说大文件被切分成N/((n+1)/2),我们再再每一块中取一行作为样本。这样的话由于大文件的总行数N,和块数(样本大小)是已知的,那么我们就可以求出n。

还是一开始的例子,可以求出n=(N/m) * 2 - 1=(1000000/100000) * 2 - 1 = 19;

于是

ei=randint(1, 19);bi=0;
fd = open('total.txt', 'r');
ofd = open('sample.txt', 'w');
while True:
    line = fd.readline();
    if not line:
        break;
    bi += 1;
    if bi != ei:
        continue;
    ofd.write(line);
    bi = 0;
    ei = randint(1, 19)

 

PS: 我实际测试的列子是总数据条数为35385665,尝试抽取100,000,使用上面的方法,最后抽取出100,167条记录,基本符合要求了。不过不能精确的抽取100,000也就是这个方法的弊端了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值