如何在两个矩阵之间进行过滤?

如何在两个矩阵之间进行过滤?

文件1:

91  23  56  44  87  77
99  34  56  22  22  95
41  88  26  79  60  27
95  55  66  69  92  25

文件2:

pass fail pass pass pass fail
pass fail pass fail fail pass
pass pass fail pass pass fail
pass pass fail pass pass fail

由于我想总结每行的总失败标记,因此这是预期的输出。

输出:

100
78
53
91

我想问一下,如何根据file2中的“fail”一词对file1进行过滤,以获得fail标记的总和。

答案1

我会使用矩阵语言来完成这样的任务,例如 GNU Octave。

假设您将通过/失败文件转换为数值,例如:

sed 's/pass/1/g; s/fail/0/g' passfail > passfail.nums

您现在可以执行以下操作:

marks    = dlmread('marks');
passfail = dlmread('passfail.nums');

for i = 1:size(marks)(1)
  sum(marks(i,:)(passfail(i,:) == 0))
end

输出:

ans =  100
ans =  78
ans =  53
ans =  91

答案2

虽然我认为使用awk有利于可移植性,但其他语言似乎更容易编写和阅读此任务。提到了 GNU Octave,但大多数机器上并未预安装。另一方面,大多数系统都预装了 python 版本。这是一个Python版本:

for marks, decisions in zip(open('file1').readlines(), open('file2').readlines()):
    row_score = 0
    for mark, decision in zip(marks.split(), decisions.split()):
        if decision == 'fail':
            row_score += int(mark)
    print(row_score)

它返回您期望的输出。

答案3

这是我的awk方法:

awk 'NR==FNR{for(i=1;i<=NF;i++) a[NR"-"i]=$i; next} \
            {for(j=1;j<=NF;j++) if($j=="fail") b[FNR]+=a[FNR"-"j]} \
         END{for(k in b) print b[k]}' file1 file2

awk 不支持二维数组,因此我们通过在同一数组索引中组合两个数字(行和字段)来组合二维数组。输出是:

100
78
53
91

答案4

awk '
  BEGIN{ pf=ARGV[2]; ARGV[2]="" }
  { getline l <pf; split(l, a); n=0;
    for(i=1;i<=NF;i++) if(a[i]=="fail") n+=$i;
    print n }
' file1 file2
100
78
53
91

就像 @Maxim 的 python 版本一样,但与所有其他答案不同,这是并行处理两个文件,逐行,而不是将其中一个整个加载到内存中。

相关内容