并行运行AWK以处理2.56亿条记录

2020-06-03 02:39:15

AWK处理海量数据;高性能计算(HPC)脚本同时调用AWK。在加脂机上提供快速且可扩展的内存解决方案。

向组织在工作中的数据挑战展示我在2018年开发的解决方案。我解决了由5个问题组成的科学出版物挖掘挑战(第4题)。我使用经典的Unix工具和现代可伸缩的HPC脚本工具来制定解决方案。该项目托管在GitHub上。大约有12支队伍参加了比赛。

阿贡国家实验室开发的名为SWIFT(不是Apple SWIFT)的HPC脚本工具用于在数据集上并发运行Awk程序,从而从根本上提高性能。SWIFT使用基于MPI的通信来并行和同步独立的任务。

还使用了其他Unix工具,如SORT、grep、tr、sed和bash。此外,还使用了jq、d3、dot/raphviz和ffmpeg。

幸运的是,我可以使用512核Intel Xeon(2.5 GHz)CPU的大内存(24T)SGI系统。所有IO都与内存(/dev/shm)绑定,即。从/dev/shm读取数据,并将数据写入/dev/shm。

AWK是轻量级的、简洁的、富有表现力的和快速的-特别是对于文本处理应用程序。有些人觉得Awk程序简洁明了,很难读懂。我必须注意使代码可读。我想看看我和Awk能走多远(天哪,我真的走了很远!)。替代工具,如现代Python库,有时会有可伸缩性限制和可移植性问题。有些人还在犹豫。之所以使用SWIFT,只是因为我熟悉它,并且相信在这种情况下它会很好地扩展。

原始数据分成两组(amine和mag),每组322个json文件,每个文件包含一百万条记录。有一个包含两个集合中出现的公共记录列表的文件可用。awk脚本(src/filterdup.awk)用于从amineDataSet中排除这些重复记录。结果,它产生了大约2.56亿条(准确地说是256,382,605条)需要处理的唯一记录。总数据大小为329 GB。数据中的某些字段为空。在相关的地方,这些记录被避免。此外,与非英文出版物有关的记录在需要时也被避免。表格数据的快照可用。选择字符串qwqw作为列分隔符,以将其与数据中已找到的文本区分开来。所有其他3个或更少的字符组合已存在于禁止将其用作分隔符的数据中。

#!/usr/bin/env awk-f#$1 Magid#$2 amineid#根据链接关系BEGIN{FS=ofs=";qwqw";}nr==fnr{a[$2]=$1}!(a中的$1)&;&;文件名~/amier/{print}

nr==fnr是一个很酷的Awk习惯用法,它确保只有第一个文件的条件为真。这是因为对于处理的每个文件,FNR(文件记录号)会被重置,但NR不会。这意味着条件NR==FNR仅对第一个文件产生TRUE。

jq用于将json数据转换为表格格式(src/json2tabular.sh)。转换后的表格文件有19个原始列(id、标题、作者、年份、引文等)和一个名为num_Authors的附加列,该列显示了一个出版物记录的作者数量。Authors列具有分号分隔符公式Authors。表格数据的进一步精选是通过使用sed删除无关的空格、方括号、转义字符和引号来实现的。

获得的一些结果被后处理,以便使用D3图形框架进行可视化。ffmpeg用于缝合流行术语的图像以创建动画。使用Dot/Graphviz构建最好的论文的海量城市网络图。

每个解决方案都使用SWIFT对322个CPU核心上的322个数据文件同时运行AWK代码。这导致大规模加速。所有的解决方案都没有超过一个小时的运行时间--大多数都不到一分钟。

确定似乎是特定领域或子领域的专家的个人或个人组。

这可以通过两种方式解决。第一种方法识别给定搜索主题(Results/Meditation_Highly_cited.txt)的引文量高于500的所有条目。

#!/usr/bin/env awk-fBEGIN{#字段分隔符FS=";qwqw";#输出字段分隔符ofs=";\t";IGNORECASE=1#可读性字段名称id=1;title=2;num_Authors=3;DOI=4;FOS_ISBN=5;doctype_issn=6;lang=7;n_citing=8;Issue=9。Publisher_pdf=16;参考=17;关键字=18;摘要=19;作者=20;}($0~Theme&;&;$num_Authors>;0&;&;$n_citing!~/null/&;&;$n_citing>;500){print$n_citing,$title,$Authors,$Year}#如何运行:#awk-v Theme=冥想-f src/pro1_p.。

第二种方法查找姓名重复伪造主题的作者姓名,每个条目中至少有一定数量的引用。这给出了一个合理的想法,谁是给定研究领域的专家人物。Results/Cancer_Research_topauths.txt中的一个这样的结果显示了作者在多个出版物中进行的癌症研究,至少有1,000次引用。

#!/usr/bin/env awk-fBEGIN{#字段分隔符FS=";qwqw";OFS=";\t";IGNORECASE=1#字段名称id=1;标题=2;num_Authors=3;DOI=4;FOS_ISBN=5;doctype_ISSN=6;lang=7;n_citing=8;Issue=9;url=10;Volume=11。关键字=18;摘要=19;作者=20;}($0~TOPIC&;&;$Num_Authors>;0&;&;$n_citing!~/null/&;&;$n_citing>;1000){#查找特定主题姓名重复的作者。#这些作者将被视为专家。Gsub(";\";";,";,$Authors)Split($Authors,a,";;";)(I In A){Split(a[i],b,";,";)#auths数组将有关键字作为身份验证名称,如果关键字重复if(b[1]!~/null/)auths[b[1]]++}}end{for(K In Auths)if(auths[k]>;1)print auths[k],k}#How to run:#awk-v title=Cancer-f src/pro1_p2.awk data/mag_Papers_sample.allcols.txt。

旁边是这个图表中被引用最多的论文的引文网络图(太大了,这里放不下)。查询阈值为20,000的最多被引用论文的历史列表的结果在Results/top_Paps.txt中。

这是通过识别集合中出现频率最高的单词来解决的。分析了标题、摘要和关键字,找到了整个集合中出现频率最高的1000个单词。从结果中过滤了几个常用词(也称为停用词)。在2300万人以上,“病人”一词出现的频率最高。前1,000个单词的完整列表可在/Results/top_1K_word_kw_abs_title.txt中找到。出版物的目标集合可以缩小到诸如年份范围之类的标准。

#!/usr/bin/env awk-f#问题陈述#确定所有出版物研究过的主题。#解决方案:#步骤1。过滤对英语记录#Step2的输入。删除不必要的内容,如标点符号、#不可打印字符和小单词,如#1个字母和2个字母单词#step3。摘录关键词、标题和摘要中使用的词语#步骤4。查找最常用的单词BEGIN{FS=";qwqw";IGNORECASE=1#字段名id=1;title=2;num_Authors=3;DOI=4;FOS_ISBN=5;doctype_ISSN=6;lang=7;n_citing=8;Issue=9;url=10;volume=11;page_start=12;page_end=13;year=14;Venue=15;Publisher_pdf=16。}#Collect Stop WordsNR==fnr{x[$1];Next}$lang~/en/&;&;($关键字!~/null/||$抽象!~/null/){#Treat Titles$title=tolower($title,a,&34;";)for(I In A)if(length(a[i])&;2&;)for(I In A)if(length(a[i])&;2&;)for(I In A)if(Length(a[i])&;2&/amp;匹配(a[i],/[a-z]/)&;&;a[i]in x==0)kw[a[i]]++#对待关键字$KEYWORKS=tolower($KEYOYS)Split($KEYWORKS,b,b,&34;,";)for(I In B)if(Length(b[i])>;2&;&;Match(b[i],/[a-z]/)&;&;b[i]in x==0)kw[b[i]++#对待摘要(计算开销很大,结果在:#top_1000_words_from_kw_abstract_title_by_freq.txt)$ACTRICAL=tolower($ASTRAGE)gsub(";\";";,";,$ASTAL)gsub(";,";,";,";,$ASTAL)Split($ASTERAL,c,";;";)for(I In C)if(length(c[i])>;2&;&;Match(c[i],/[a-z]/)&;&;c[i]in x==0)kw[c[i]]++}end{for(K In Kw){if(kw[k]>;1000)打印kw[k],k}}#如何运行:lc_all=C awk-f pro2.awk stop_words.txt\../miner_Papers_allols_excl/amer_Papers_*.allcols.excl.txt\../mag_Papers_allols/mag_Papers_*.allcols.txt\|sorte-nr>;freq.txt。

导入文件;导入Unix;/*app定义我们要运行的内容、输入参数、stdout应该放到的位置等。*/app(File Out)myawk(FILE BUCKPRG,FILE STOP_WORD,FILE INFILE){";/usr/bin/awk";";-f";jauprog stop_word infile@stdout=out}/*填充输入数据*/file miner[]=glob(";/dev/shm/miner_mag_Papers/*.txt";);/*此处将收集每个调用的输出*/file outfiles[];foreach v,i in miner{outfiles[i]=myawk(input(";/home/km0/SMC18/src/pro2.awk";),input(";/home/km0/smc18/data/stop_words.tx;),input(";/home/km0/smc18/data/stop_words.tx.),input(";/home/km0/smc18/data/stop_words.tx.)。}/*将所有输出合并到一个文件中*/FILE JOINED<;";joined.txt";>;=cat(Outfiles);/*运行此快速应用后:awk';{a[$2]+=$1}end{for(K In A)print a[k],k}';joined.txt|ort-nr>;freq.txt*/。

这可以通过识别其中包含搜索主题的记录的作者从属关系来解决。在城市、大学和国家这三个数据库中搜索从属关系,以找出该研究的地理位置。将结果汇总到印刷机

这个问题可以通过三种截然不同的方式解决。第一种方法对数据库进行处理,以找出任何给定的两个主题每年一起出现的情况。它会生成一份年份列表,并列出这两个主题在该年的单个出版物中出现的次数。例如,下面的图表显示了多年来“肥胖”和“糖”这两个术语在出版物中是如何结合在一起的。

#!/usr/bin/env awk-f#问题陈述#确定主题如何随时间变化。#下面的解决方案1将搜索提到的任意两个主题#并显示这两个主题按年出现的次数BEGIN{#Field Separator FS=";qwqw";IGNORECASE=1#Field Names id=1;Title=2;Num_Authors=3;DOI=4;FOS_ISBN=5;doctype_ISSN=6;lang=7;n_citing=8;Issue=9;url=10;Volume=11。关键词=18;摘要=19;作者=20;}$lang~/en/&;&;$0~topic1&;&;$0~topic1&;&;$0~topic2{a[$Year]++}end{n=asorti(a,b)printf(";主题趋势:%s,%s\n&34;,topic1,topic2)(i=1;i<。%d:-%d\n";,b[i],a[b[i]])}#按如下方式运行:#awk-v topic1=肥胖-v topic2=糖-f代码/pro4.awk miner_mag_Papers/*.txt。

第二种方法找到每年影响最大的论文,并提取这些论文中的关键词。影响是根据那一年被引用最多的论文计算出来的。此任务的结果以年份、关键字、引用三元组的形式存储在Results/Year_Trending_keywords.txt中。

#!/usr/bin/env awk-f#问题陈述#确定主题如何随时间变化。#解决方案2是根据BEGIN{FS=OFS=";qwqw";IGNORECASE=1#字段名称id=1;标题=2;num_Authors=3;DOI=4;FOS_ISBN=5;doctype_issn=6;lang=7;n_citing=8;Issue=9;url=10;Volume=11;page_start=8找出被引用次数最高的论文#年,并计算出该论文所基于的主题{FS=ofs=";qwqw";IGNORECASE=1#Field Names=1;Title=2;num_Authors=3;DOI=4。摘要=19;作者=20;}$lang~/en/&;&;$Year!~/NULL/&;&;$Year<;2020&;&;$KEYENTS!~/NULL/&;&;$n_CITION!~/NULL/&;&;MAX[$Year]{MAX[$Year]=$n_CITIONS;a[$Year]=$KEYOYES}end{n=asorti。i++)通过SWIFT并行运行打印b[i],a[b[i]],max[b[i]]}#。如果是串行的,请按如下方式运行:#awk-f code/pro4_p2.awk miner_mag_Papers/*.txt>;Year Way_Trending_keywords.txt。

第三种方法找出每年出现频率最高的10个术语,以找出这些年来这些话题是如何流行和过时的。此处是一段MKV动画视频,显示了1800至2017年间单词的泡沫图。所有单词的文件列表可在Results/Trending_Words_by_Year中找到。2002年的热门词汇泡沫化截图如下所示:

#!/usr/bin/env awk-f#查找每年最热门的10个主题,看看它们在趋势中如何出现/消失#我们通过将关键字、标题和摘要写入以它们出现的年份命名的文件并对这些文件进行后处理来实现这一点BEGIN{FS=";qwqw";IGNORECASE=1#字段名称id=1;title=2;num_Authors=3;DOI=4;FOS_ISBN=5;page_start=12;page_end=13;年份=14;地点=15;Publisher_pdf=16;参考=17;关键字=18;摘要=19;作者=20;}#收集停用词NR==fnr{x[$1];Next}$lang~/en/&;&;$n_citing>;0&;&;$Year=yr&;&;$关键字!~/null/{#将标题、关键字和摘要写入按出现年份命名的文件#对待标题$TITLE=tolower($TITLE,a,a,";";)for(I In A)if(length(a[i])>;2&;Match(a[i],/[a-z]/)&;&;)(I In A)if(length(a[i])>;2&;Match(a[i],/[a-z]/)&;&;a[i]in x==0)如果(I In B)if(Length(b[i])>;2&;&;Match(b[i])&;&;匹配(b[i],/[a-z]/)&;&;,打印(i]in x==0)的[i]#Treat Keypes$Keyons=tolower($Keyons)gsub(";\";";,";,";,$Keyons)Split($Keyons,b,&34;,";,";)。b[i]in x==0)为(I In C)打印b[i]#Treat Abstral$Abstra=tolower($Summary)gsub(";\";";,";,";,";,";,";,$Summary)拆分($Summary,c,";";)if(Length(c[i])>;2&。Match(c[i],/[a-z]/)&;&;c[i]in x==0)打印c[i]}#进行以下后处理:#for i in 18??19??20??#do(grep-o-E';\w+';$i|TR[A-Z][a-z]\#|sed-e';s/null//g';-e';s/^.$//g';-e/^..$//g';-e';s/^[0-9]*$//g';\#|awk NF|fgrep-v-w-f stop_words.txt\#|SORT|uniq-c|SORT-nr\#|head-1

这有一个简单的解决方案:找到新提案上的关键字。如果这些关键字出现在现有发布记录中,则它是可疑的。可以通过关键字之间的逻辑OR找到广泛的嫌疑人列表,这些关键字可以用逻辑AND缩小范围。关键字可以在OR和AND中任意组合。结果文件/Results/Suspects.txt显示了1400多名来自英文报纸的疑似关键词及其组合:电池、电子、锂和能源。HPC实施将在26秒内完成。下面的AWK代码。

#!/usr/bin/env awk-f#问题陈述#给出研究建议,确定提议的工作以前是否#已完成。#解决方案:找到新提案中的关键字。#如果这些关键字出现在现有出版物记录中,则为可疑。BEGIN{FS=";qwqw";IGNORECASE=1#字段名id=1;标题=2;num_Authors=3;DOI=4;FOS_ISBN=5;doctype_ISSN=6;lang=7;n_citing=8;Issue=9;url=10;volume=11;page_start=12;page_end=13;Year。}#topic1..。topic4在命令行$0~topic1&;&;$0~topic2&;&;$0~topic3&;&;$0~topic4&;&;$lang~/en/&;&;$Authors!~/null/{print$id,$title,$Authors,$Year}中提供。

我展示了如何利用经典的Unix工具来解决现代问题,数百万条记录可以在不到一分钟的时间内大规模处理。就数据本身而言,似乎生物科学研究在PU中占据主导地位。

..