需要优化perl脚本吗
我有两个文件,每个大约700000行,看起来像: 文件1 文件2 我有一个脚本,我在其中查找文件1中的字段1和4与文件2中的字段1和5匹配的行。然后,如果文件1中的字段5和6与文件2中的字段3和4匹配,我只是打印出文件2中的行。但是,如果字段3和4(文件2)相对于字段5和6(文件1)翻转,我将从文件2中获取字段7的倒数,并使用调整后的字段7打印行:需要优化perl脚本吗,perl,optimization,Perl,Optimization,我有两个文件,每个大约700000行,看起来像: 文件1 文件2 我有一个脚本,我在其中查找文件1中的字段1和4与文件2中的字段1和5匹配的行。然后,如果文件1中的字段5和6与文件2中的字段3和4匹配,我只是打印出文件2中的行。但是,如果字段3和4(文件2)相对于字段5和6(文件1)翻转,我将从文件2中获取字段7的倒数,并使用调整后的字段7打印行: #! perl -w
#! perl -w
use strict;
use warnings;
my @kgloci;
open( my $loci_in, "<", "File1" ) or die $!;
while (<$loci_in>) {
my ($chr, $snpID, $dist, $bp, $A1, $A2) = split;
next if m/Chromosome/;
push @kgloci, [$chr, $snpID, $dist, $bp, $A1, $A2];
}
close $loci_in;
my $filename = shift @ARGV;
open( my $input, "<", "File2" ) or die $!;
while (<$input>) {
next if m/hg19chrc/;
my ($chr, $snpID, $A1, $A2, $bp, $info, $or, $se, $p, $ngt) = split;
foreach my $kglocus (@kgloci) {
if ( $chr == $kglocus->[0]
and $bp == $kglocus->[3]
and $A1 eq $kglocus->[4] ){
print "$chr $snpID $A1 $A2 $bp $info $or $se $p $ngt\n";
next;
}
elsif ( $chr == $kglocus->[0]
and $bp == $kglocus->[3]
and $A1 eq $kglocus->[5]){
my $new_or = 1/$or;
print "$chr $snpID $A1 $A2 $bp $info $new_or $se $p $ngt\n";
next;
}
}
}
close($input);
#!perl-w
严格使用;
使用警告;
我的@kgloces;
打开(“中的my$u),使用散列而不是数组
以下脚本应提供与您相同的输出(除非文件1中的A1和A2相同):
结果:旧脚本需要16秒,新脚本少于0.1秒。对于较大的文件(700_000行),新脚本需要4秒。使用哈希而不是数组
以下脚本应提供与您相同的输出(除非文件1中的A1和A2相同):
结果:旧脚本需要16秒,新脚本小于0.1s。对于较大的文件(700_000行),新脚本需要4秒。此脚本非常快,谢谢。但是我注意到您的脚本在某些情况下为字段7输出了不正确的值。例如,其中File1为:22 rs1296744 0 17968155 A G
而File2为22 rs1296744 A G 17968155 0.956 0.9977 0.0108 0.831 0
输出为22 rs1296744 A G17968155 0.956 1.00230530219505 0.0108 0.831 0
其中字段7实际上应保持为0.9977。奇怪的是,我的脚本为这一行输出了两行,一行带有正确的字段7,另一行带有调整后的字段7@theo4786:可能还有另一行影响输出。只有这两行,我从中得到相同的结果两个脚本。是的,您是对的,在这些情况下,文件1中有两个输入行包含重复的字段1和4,但其他字段中的值不同。@theo4786:您能显示这些行并指示正确的输出吗?例如,文件1中的这些行:22 rs1296744 0 17968155 A G
和22 rs201055523 0 17968155 AGG A代码>。正确的输出是22 rs1296744 A G 17968155 0.956 0.9977 0.0108 0.831 0
。我相信我可以通过$lookup{“$chr:$snpID:$bp:$A1”实现这一点
,因为我想在$snpID也匹配的地方输出。这个脚本非常快,谢谢。但是我确实注意到您的脚本在某些情况下为字段7输出了不正确的值。例如,其中File1是:22 rs1296744 0 17968155 A G
而File2是22 rs1296744 A G 17968155 0.956 0.9977 0.0108 0.831 0
输出是<代码>22 rs1296744 A G 17968155 0.956 1.0023053021505 0.0108 0.831 0
其中字段7实际上应保持为0.9977。奇怪的是,我的脚本为这一行输出了两行,一行带有正确的字段7,另一行带有调整后的字段7@theo4786当前位置可能还有另一行影响输出。只有这两行,我得到两个脚本的结果相同。是的,您是对的,在这些情况下,文件1中有两个输入行包含重复的字段1和4,但在其他字段中有不同的值。@theo4786:您能显示这些行并指示正确的输出吗?例如,文件1中的这些行:22 rs1296744 0 17968155 A G
和22 rs201055523 0 17968155 AGG A
。正确的输出是22 rs1296744 A G 17968155 0.956 0.9977 0.0108 0.831 0
。我相信我可以通过$lookup{“$chr:$snpID:$bp:$A1”}
,因为我希望$snpID也匹配的输出。将文件导入数据库?将文件导入数据库?
hg19chrc snpid a1 a2 bp info or se p ngt
1 rs4951859 C G 729679 0.631 0.97853 0.0173 0.2083 0
1 rs142557973 T C 731718 0.665 1.01949 0.0198 0.3298 0
22 rs1001008 A G 44928369 0.969 0.98649 0.0107 0.2023 0
#! perl -w
use strict;
use warnings;
my @kgloci;
open( my $loci_in, "<", "File1" ) or die $!;
while (<$loci_in>) {
my ($chr, $snpID, $dist, $bp, $A1, $A2) = split;
next if m/Chromosome/;
push @kgloci, [$chr, $snpID, $dist, $bp, $A1, $A2];
}
close $loci_in;
my $filename = shift @ARGV;
open( my $input, "<", "File2" ) or die $!;
while (<$input>) {
next if m/hg19chrc/;
my ($chr, $snpID, $A1, $A2, $bp, $info, $or, $se, $p, $ngt) = split;
foreach my $kglocus (@kgloci) {
if ( $chr == $kglocus->[0]
and $bp == $kglocus->[3]
and $A1 eq $kglocus->[4] ){
print "$chr $snpID $A1 $A2 $bp $info $or $se $p $ngt\n";
next;
}
elsif ( $chr == $kglocus->[0]
and $bp == $kglocus->[3]
and $A1 eq $kglocus->[5]){
my $new_or = 1/$or;
print "$chr $snpID $A1 $A2 $bp $info $new_or $se $p $ngt\n";
next;
}
}
}
close($input);
#! /usr/bin/perl
use warnings;
use strict;
my %lookup;
open my $LOCI, '<', 'File1' or die $!;
while (<$LOCI>) {
next if /Chromosome/;
my ($chr, $snpID, $dist, $bp, $A1, $A2) = split;
$lookup{"$chr:$bp:$A1"} = 1;
$lookup{"$chr:$bp:$A2"} = 2;
}
open my $IN, '<', 'File2' or die $!;
while (<$IN>) {
next if m/hg19chrc/;
my ($chr, $snpID, $A1, $A2, $bp, $info, $or, $se, $p, $ngt) = split;
my $new_or = ( sub {},
sub { shift },
sub { 1 / shift },
)[ $lookup{"$chr:$bp:$A1"} || 0 ]->($or);
print "$chr $snpID $A1 $A2 $bp $info $new_or $se $p $ngt\n"
if defined $new_or;
}
perl -MList::Util=shuffle -wE '
$i = 1;
$pos = 1;
for (1 .. 10000) {
say join " ", $i, "rs$pos", int rand 5, 1000 + int rand 10000,
(shuffle(qw(A C T G)))[0,1];
++$i if rand 1 > .99;
$pos += int rand 20;
}' > File1
perl -wE '
$i = 1;
$pos = 1;
for (1 .. 10000) {
say join " ", $i, "rs$pos", (map qw(A C T G)[rand 4],1,2),
1000 + int rand 10000, rand 1, rand 5, rand 1, rand 1,
int rand 3;
++$i if rand 1 > .99;
$pos += int rand 20;
}' > File2