Skip to main content
 首页 » 编程设计

python之低效代码 : comparing combining different columns from different files awk or perl

2025年05月04日14hnrainll

我有两个文件,我想将文件 1 的第 2 列与文件 2 的列 NF 进行匹配。如果它们匹配,我想输出 file2 的整行,加上 file1 的第 5 列和文件 1 的第 5 列最后乘以文件 2 的 NF-2 列。这些文件具有不同的长度。

我有以下两种文件类型:

文件1

xx  name1 1 we    freq1 
xy  name2 2 wer   freq2 
xz  name3 3 werf  freq3 

文件2

..... value1 cv name1 
..... value4 cvb name4 
..... value3 cvb name3   
..... value1 vbn name5 

期望的输出

..... value1 cv name1 freq1 (freq1*value1) 
..... value3 cvb name3 freq3 (freq3*value3) 

我已经尝试使用 awk 来完成此操作。

awk 'FNR==NR { two[$0]++; next } { for (i in two) { split(i, one); if (one[2] == $NF) print $0, one[5], $(NF-2)*one[5] } }' file1 file2 > file3

它可以工作,但效率极低,并且让我的电脑在一段时间后崩溃。 每个文件大约有 100,000 行。也许我应该为此使用 perl 或 python?或者有没有办法读取文件 2?谢谢!

请您参考如下方法:

听起来最好的方法是从 file1 中读取所有相关列(2 和 5)到散列中,然后只处理 file2 一行一行。

如果散列使用 file1 的第 2 列作为键,那么它可以简单地用 file2 最后一列的值来索引,看看是否有对应的另一个文件中的值。

然后所需要做的就是打印 file2 记录中的值,以及使用散列元素中的数据计算出的值。

本程序演示。变量名称有点模糊,因为您没有为问题中的字段赋予意义,所以我所能做的就是引用文件和列号。

我不得不输出 string*string 而不是实际产品,因为您的数据没有数值。

use strict; 
use warnings; 
use autodie; 
 
open my $fh1, '<', 'file1'; 
my %file1; 
while (<$fh1>) { 
  my ($f1_2, $f1_5) = (split)[1,4]; 
  $file1{$f1_2} = $f1_5; 
} 
 
open my $fh2, '<', 'file2'; 
while (<$fh2>) { 
  my @f2_rec = split; 
  my ($f2_nm2, $f2_n) = @f2_rec[-3,-1]; 
  if (my $f1_5 = $file1{$f2_n}) { 
    print join(' ', @f2_rec, $f1_5, "$f1_5*$f2_nm2"), "\n"; 
  } 
} 

输出

..... value1 cv name1 freq1 freq1*value1 
..... value3 cvb name3 freq3 freq3*value3