我有一个文本文件,大约有100000000行,每一行的类型如下:
string num1 num2 num3 ... num500
string num1 num2 num3 ... num40
我想找到这个文件中出现的最大数字。
我当前的代码读取每一行,用空格将其拆分,并将最大的数字存储在当前行中,然后将其与下一行的最大数字进行比较,并保留两者中较大的一个。
with open(filename,'r') as f:
prev_max = -1
for line in f:
line = [int(n) for n in line.split(' ')[1:]]
max = max_num(line)
if max > prev_max:
prev_max = max
但这要花很长时间。有更好的方法吗?
我对使用awk或其他shell命令的解决方案也持开放态度。
编辑:添加了我如何阅读文件。
4条答案
按热度按时间l7mqbcuq1#
对于awk来说,这是一项微不足道的任务。
如果可以保证文件不全是零或负数,则可以删除
NR==1{m=$2}
部分。uajslkp62#
试试这个Perl解决方案
hfyxw5xn3#
我想编写一个awk脚本,但不使用
for
循环列,以便与for
循环解决方案(如@oguzismail的 trivial)比较执行时间。值在0-2^32之间。我尝试使用RS
只比较列2-100,但由于这需要正则表达式,它降低了执行速度。使用tr
来交换空间和换行符,我已经非常接近了:cat <(echo 0) file | tr ' \n' '\n '
的输出:使用的 trivial 解决方案:
而我的
tr
+ awk花费了:(令人惊讶的是,如果我先用
tr
将数据预处理成一个文件,然后用awk读取它,它不会更快,实际上大多数时候会更慢)所以,我决定测试一下我生疏的C语言技能,以设定某种基准(手册页相当不错,还有谷歌):
结果是:
哦,使用mawk而不是gawk,结果几乎减半。
cbeh67ev4#
您不需要
C
或C++
来提高速度-awk
有很多优点:我创建了一个
957 MB
合成文件,其中包含0
和2^48 - 1
之间的随机整数,加上擦除所有偶数位的尾部(以减少但不消除由于
rand()
本身均匀分布而导致的十进制#位分布朝向高侧的聚集效应):-- * 这也意味着真正的最小值是
1
,而不是0
*...而
awk
只需**6.28 secs
扫描68.6 mn rows
**(70 mn
重复数据消除前)即可找到最大的::一个一个一个一个一个x一个一个二个一个x一个一个三个一个x一个一个x一个四个一个
在这样的吞吐率下,与单个
awk
示例相比,使用类似gnu-parallel
的示例可能只能产生很小的增益。