项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步
现在有一个260万行的文本,希望从中随机选择100万行。以下这些方法,经过博主的验证,都是实际可行的,希望能给有需要的同学带来一些帮助。
1.sort的方式
二话不说,直接上代码。
#!/bin/bash
start=$(date +%s)
echo $start
sort -R 260whiteall | head -1000000 >result
end=$(date +%s)
echo $end
echo "cost time is: $(($end - $start))"
真正的逻辑其实就是sort那一行。sort是linux shell中非常常用的命令,-R选项,估计大家都能猜到。没错,就是random啦!所以,先第文本随机排序,然后再取前一百万行,自然就达到了我们的目的!
关于这种方式,有两点需要注意:
1.-R选项好像不是所有unix系统自带的。例如在mac的unix里,man sort查看sort文档,你就会发现没有-R选项。所以在使用的时候需要注意,系统是否自带sort -R的方式。
2.既然是sort,那同学们肯定就得考虑到一个问题:效率。因为排序本身是个比较耗时的操作,尤其是数据量比较大的时候。一般比较排序的方式复杂度为
n
l
o
g
n
nlogn
nlogn,所以当数据量大了以后,排序的复杂度增加是很可怕滴。在本实例中,让代码run起来,最后的输出如下:
1475325594
1475325790
cost time is: 196
可以看出,这种方式的耗时达到了196s!相对来说,并不是一种很高效的方式。所以总结起来来看,这种方式适用于比较小的数据量,不太适合比较大的数据量!
2.逐行选取的方式
二话不说,直接上代码
#!/usr/bin/env python
#coding:utf-8
import random
import time
def handle():
f = open("260whiteall","r")
fw = open("100millin","w")
count = 0
num = 0
for line in f.readlines():
num += 1
if num % 2 == 0 and count <= 1000000:
count += 1
fw.writelines(line + "\n")
elif count > 1000000:
break
handle()
思路很简单粗暴,每隔一行取一行,从而达到近似随机选取的效果。
如果是200万中随机选100万,这种方式还是可以接受的。但如果是260万选100万的话,这种方式就不太好了。因为200万行以后的文本,一行都没被选中。所以本质上这不是一种好方法。
3.shuffle的方式
二话不说,直接上代码
#!/usr/bin/env python
#coding:utf-8
import random
import time
def test():
start = time.clock()
f = open("260whiteall","r")
fw = open("100million","w")
raw_list = f.readlines()
random.shuffle(raw_list)
for i in range(1000000):
fw.writelines(raw_list[i])
end = time.clock()
print "cost time is %f" %(end - start)
test()
使用了python中的shuffle()方法,将序列中的所有元素随机排列。然后再取前一百万行输出即可。
使用这种方式需要注意的一个小点就是:
shuffle()方法无法直接调用,需要导入random模块,然后通过random模块静态调用。
看看此种方式的耗时:
cost time is 7.390000
可以看出,比之前的196s还是快了接近两个数量级!
而且,这种方式最大的好处是对平台没有限制。毕竟,在windows里是没法直接使用sort的!