对文本文件中第 N 列求和的最快方法

对文本文件中第 N 列求和的最快方法

我有一个 CSV 文件(其中字段分隔符确实是逗号),有 8 列和几百万行。这是一个示例:

1000024447,38111220,201705,181359,0,12,1,3090
1064458324,38009543,201507,9,0,1,1,1298
1064458324,38009543,201508,9,0,2,1,90017

打印给定列中所有数字的总和以及读取的行数的最快方法是什么?你能解释一下是什么使它更快吗?

答案1

GNU 数据混合

$ datamash -t, count 3 sum 3 < file
3,604720

一些测试

$ time gawk -F',' '{ sum += $3 } END{ print sum, NR }' longfile
604720000000 3000000

real    0m2.851s
user    0m2.784s
sys     0m0.068s

$ time mawk -F',' '{ sum += $3 } END{ print sum, NR }' longfile
6.0472e+11 3000000

real    0m0.967s
user    0m0.920s
sys     0m0.048s

$ time perl -F, -nle '$sum += $F[2] }{ print "$.,$sum"' longfile
3000000,604720000000

real    0m3.394s
user    0m3.364s
sys     0m0.036s

$ time { cut -d, -f3 <longfile |paste -s -d+ - |bc ; }
604720000000

real    0m1.679s
user    0m1.416s
sys     0m0.248s

$ time datamash -t, count 3 sum 3 < longfile
3000000,604720000000

real    0m0.815s
user    0m0.716s
sys     0m0.036s

因此mawk, 和datamash似乎是这群人中的最佳选择。

答案2

Awk是一种用于处理文本文件的快速且高性能的工具。

awk -F',' '{ sum += $3 }
           END{ printf "Sum of 3rd field: %d. Total number of lines: %d\n", sum, NR }' file

示例输出:

Sum of 3rd field: 604720. Total number of lines: 3

概念说明
我必须注意,所有这些非awk替代方案仅对于此类“理想”数字列才能运行得更快。您只需要拥有稍微复杂的格式(例如,在计算之前要删除一些附加信息<1064458324:a,<38009543:b,<201507:c,<9:d,<0:e,<1:f,<1:g,1298),所有这些速度优势都会消失(更不用说其中一些无法执行需要处理)。

答案3

您可以使用cut提取字段、在数字之间paste插入符号并对它们求和。您可以用来计算行数。+bcwc

不过,我不确定超过数百万行的性能会如何。但绩效的黄金法则是,不要猜测,要衡量。您需要对任何解决方案进行分析,以查看它是否提供了您所需的性能,并确定任何更改是否会提高或降低性能以及提高或降低的程度。

这是一个对给定字段求和并打印行数的解决方案:

echo -n "Sum: "
cut -d, -f3 <file |paste -s -d+ |bc
echo -n "Lines: "
wc -l <file

输出:

Sum: 604720
Lines: 3

该字段由此处的-f#参数 to指定。cutcut -f3

相关内容