0

私は 2 つのファイルを持っています。そのうちの 1 つは次のような単なる列ベクトルです。

1x23
1y21
1z21
1z25

other は次の形式の行列です。

1x23 1x24 1y21 1y22 1y25 1z22 class
2000 3000 4000 5000 6000 7000 Yes
1500 1200 1100 1510 1410 1117 No

最初に、最初のファイルのどの行が 2 番目のファイルの最初の行と一致するかを調べたいと思います。次に、最初のファイルの列と一致する 2 番目のファイルの列をコピーし、それらを 2 番目のファイルに追加します。したがって、1x23 と 1y21 が一致するため、2 番目の 2 つの列をコピーして、クラス変数の前に追加します。

私は自分の結果が

1x23 1x24 1y21 1y22 1y25 1z22 1x23 1y21 class
2000 3000 4000 5000 6000 7000 2000 4000 Yes
1500 1200 1100 1510 1410 1117 1500 1100 No

perl を使用して 3 の for ループを使用してコーディングしましたが、データが非常に大きいため、クラッシュしました。これを行うための効率的な方法があるべきだと思います。

4

5 に答える 5

1

これは長くて複雑ですが、IMHOの明確なアプローチです。

use strict;
use warnings;

open(my $data, '<', 'data.txt');

# read first row from the data file
my $line = <$data>;
chomp $line;

# create a list of columns
my @cols = split / /, $line;

# create hash with column indexes
my %colindex;
my $i = 0;
foreach my $colname (@cols) {
        $colindex{$colname} = $i++;
}

# Save last column ('class')
my $lastcol = pop @cols;

# get input (column names)
open(my $input, '<', 'input.txt');
my @colnames = <$input>;
close $input;

# append column names to array if there is a match
foreach (@colnames) {
        chomp;
        if (exists $colindex{$_}) {
                push @cols, $_;
        }
}

# Restore the last column
push @cols, $lastcol;

# Now process your data
open(my $out, '>', 'output.txt');

# write the header column
print $out join(" ", @cols), "\n";

while ($line = <$data>) {
        chomp $line;
        my @l = split / /, $line;
        foreach my $colname (@cols) {
                print $out $l[$colindex{$colname}], " ";
        }
        print $out "\n";
}

close $out;
close $data;
于 2013-11-14T20:23:35.230 に答える