微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用python和gnu-parallel在输出处理测试中仅保留一个标题行? 问题可能的解决方案说明专业人士缺点

如何解决如何使用python和gnu-parallel在输出处理测试中仅保留一个标题行? 问题可能的解决方案说明专业人士缺点

问题

通常,我需要处理多个CSV文件的目录并生成一个输出文件。通常,我依靠并行的GNU来并行运行这些任务。但是,我需要一种方法来丢弃除返回输出的第一个作业之外的所有作业的第一行(标题)。

要具体说明,请想象一个目录,其中包含几个CSV文件...

x,y
1,1.2
2,5.3
3,6.0

然后,有一些(Python)脚本,称为calc.py,用于清除数据或进行计算...

import csv
import math
import sys

rdr = csv.DictReader(sys.stdin)
wtr = csv.DictWriter(sys.stdout,fieldnames=['x','y','siny'])
wtr.writeheader()

for row in rdr:
    row['siny'] = math.sin(float(row['y']))
    wtr.writerow(row)

然后我们可以与GNU并行并行处理数据文件...

parallel --lb python calc.py '<' {} ::: $(ls -1 *.csv)

但是,这将产生多个标题行。例如...

x,y,siny
1,1.2,0.9320390859672263
2,5.3,-0.8322674422239013
3,6.0,-0.27941549819892586
x,siny
4,7.2,0.7936678638491531
5,2.2,0.8084964038195901
6,0.9,0.7833269096274833

我正在寻找一种简单的方法(最好是parallel的选项),以仅将第一行标题行保留在 output 中。手册中与标题相关的内容似乎与输入有关。

可能的解决方

我看到了一些选择,但是我什么都不喜欢...

  1. 没有calc.py输出标头,而是在并行运行前回显标头。缺点是必须知道标题,否则我们需要在运行python calc.py data1.csv | head -n 1之前通过运行parallel之类的内容来窥视标题
  2. 将每个作业的输出保存到单独的文件中,然后事后将它们连接起来(例如,用xsvtailsed等),从除首先。这样做的缺点是必须管理磁盘上的其他文件,然后再清理它们。
  3. 编写另一个执行此操作的程序,并将parallel的结果传递给该程序。
    • 似乎需要占用大量cpu才能将输出的每一行与第一行进行比较,而且我们知道很少有记录会匹配。
    • 假定没有有效的数据记录与标题行匹配。

解决此问题的最佳方法是什么? 是否有一个选项可以告诉parallel忽略每个作业输出中除一个标题行外的所有标题行?

解决方法

如何调整选项1:

使程序采用两个参数:文件作业号

if jobnumber == 1:
  output header

要确保首先打印作业1,请使用--keep-order

parallel --keep-order python calc.py {#} '<' {} ::: *.csv

GNU Parallel会将正在运行的作业的输出缓存在/ tmp中以序列化输出,该输出可能比--lb慢或不慢。

通常,您可以执行以下操作:

parallel -k python 'calc.py < {} {= uq; $_ = seq()==1 ? "" : "| tail +2" =}' ::: *.csv

uq自20190722开始可用。

您将运行tail,因此它可能会稍微慢一些。在我的系统上,tail每个核心可提供0.5 GB / s的速度。

,

AFAIK,GNU Parallel没有提供任何这样的选项以仅在输出中写入标头一次

但是一种简单的方法可以是使用awk只输出标题行一次,就像

parallel --lb python calc.py '<' {} ::: $(ls -1 *.csv) | awk 'NR==1 { header=$0; print $0; next; } $0 != header'

说明

NR是awk中的行号。当行号为1时,它将存储在变量header中,并且仅打印一次。如果之后有任何行与标头完全匹配,它将被忽略

专业人士

  • 您不需要事先知道标题
  • 您不需要将输出保存到单独的文件中
  • 无需更改代码

缺点

  • 假设没有数据行与标题完全匹配
  • 如果没有标题,它将修剪输出的第一行和所有相同的行
  • 字符串匹配的开销很小

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。