我目前正在尝试将32 x 48的矩阵文件传递给Perl中的多维数组。我能够访问所有值,但访问特定值时遇到问题。任何帮助将不胜感激。我已经设置了数据集的链接以及我下面的代码。
以下是数据集的链接: http://paste-it.net/public/x1d5301/
这就是我现在的代码。
#!/usr/bin/perl
open FILE, "testset.txt" or die $!;
my @lines = <FILE>;
my $size = scalar @lines;
my @matrix = (1 .. 32);
my $i = 0;
my $j = 0;
my @micro;
foreach ($matrix)
{
foreach ($lines)
{
push @{ $micro[$matrix]}, $lines;
}
}
答案 0 :(得分:7)
似乎您不理解$matrix
仅在@matrix
后面紧跟一个数组索引器[ $slot ]
时才表示$matrix
。否则,@matrix
是与%matrix
完全不同的变量(两者都与#!/usr/bin/perl
use English;
不同)。请参阅perldata。
$MATCH
不要!使用英语 - 那样!
这会带来$PREMATCH
,$POSTMATCH
和$&
并导致可怕的$'
,$`,open FILE, "testset.txt" or die $!;
惩罚。你应该等到使用一个英文变量,然后再导入它。
my @lines = <FILE>;
两件事:1)使用lexical file handles,2)使用三个{arg open
。
my $size = scalar @lines;
my @matrix = (1 .. 32);
my $i = 0;
my $j = 0;
my @micro;
只要我选择:不要啜饮大文件。 (这不是这种情况,但这是一个很好的警告。)
foreach ($matrix) {
我看到我们在"PROFIT!!"阶段......
$matrix
您没有变量@matrix
,您有变量 foreach ($lines) {
。
$lines
push @{ $micro[$matrix]}, $lines;
}
}
也是如此。
use strict;
use warnings;
use English qw<$OS_ERROR>; # $!
open( my $input, '<', 'testset.txt' ) or die $OS_ERROR;
# I'm going to assume space-delimited, since you don't show
my @matrix;
# while ( defined( $_ = <$input> ))...
while ( <$input> ) {
chomp; # strip off the record separator
# load each slot of @matrix with a reference to an array filled with
# the line split by spaces.
push @matrix, [ split ]; # split = split( ' ', $_ )
}
重写:
{{1}}
答案 1 :(得分:3)
如果您打算做一些数学运算,可以考虑使用PDL(Perl数据语言)。您可以在操作之前轻松设置矩阵:
use 5.010;
use PDL;
use PDL::Matrix;
my @rows;
while( <DATA> ) {
chomp;
my @row = split /\s+/;
push @rows, \@row;
}
my $a = PDL::Matrix->pdl( \@rows );
say "Start ", $a;
$a->index2d( 1, 2 ) .= 999;
say "(1,2) to 999 ", $a;
$a++;
say "Increment all ", $a;
__DATA__
1 2 3
4 5 6
7 8 9
2 3 4
输出显示矩阵演变:
Start
[
[1 2 3]
[4 5 6]
[7 8 9]
[2 3 4]
]
(1,2) to 999
[
[ 1 2 3]
[ 4 5 999]
[ 7 8 9]
[ 2 3 4]
]
Increment all
[
[ 2 3 4]
[ 5 6 1000]
[ 8 9 10]
[ 3 4 5]
]
在矩阵的每个成员上运行任意和复杂的操作都有相当大的力量,就像我向每个成员添加1一样。你完全跳过循环杂技。
不仅如此,PDL还有很多特殊的东西可以使数学运算速度非常快并且占用内存很少。您想要做的一些事情可能已经实施。
答案 2 :(得分:2)
您可能需要chomp
值:
chomp( my @lines = <FILE> );
答案 3 :(得分:1)
我正在制作这个CW,因为它的唯一目的是澄清我在@Axeman's answer的评论中提出的切入点。见perldoc -f split:
/\s+/
上的拆分类似于split(' ')
,但任何前导空格都会产生空的第一个字段。没有参数的拆分确实在内部split(' ', $_)
。
#!/usr/bin/perl
use YAML;
$_ = "\t1 2\n3\f4\r5\n";
print Dump { 'split' => [ split ] },
{ "split ' '" => [ split ' ' ] },
{ 'split /\s+/' => [ split /\s+/ ] }
;
输出:
--- split: - 1 - 2 - 3 - 4 - 5 --- split ' ': - 1 - 2 - 3 - 4 - 5 --- split /\s+/: - '' - 1 - 2 - 3 - 4 - 5
答案 4 :(得分:1)
我看到这个问题很老了,但是正如作者刚刚编辑过这个问题,也许这仍然是有趣的。此外,数据的链接已经死亡,但由于其他答案使用空格作为分隔符,我也会这样做。
此答案演示了Tie::Array::CSV
,它允许随机访问CSV(或使用Text::CSV
可解析的其他文件)。
#!/usr/bin/env perl
use strict;
use warnings;
use Tie::Array::CSV;
## put DATA into temporary file
## if not using DATA, put file name in $file
use File::Temp ();
my $file = File::Temp->new();
print $file <DATA>;
##
tie my @data, 'Tie::Array::CSV', $file, {
text_csv => {
sep_char => " ",
},
};
print $data[1][2];
__DATA__
1 2 3 4 5
6 7 8 9 1
2 3 4 5 6