1

我有一个 tsv 文件 foo.tsv,其名称为:“a”、“b”、“c”、“d”。我想读取这个文件并将其内容加载到 PDL 矩阵。文件 foo.tsv 如下所示:

a   b   c   d
1   6   7   4
2   7   6   10
3   8   5   6
4   9   4   8
5   10  3   7

我使用此代码将文件读取到矩阵并打印它:

use PDL::Core qw(pdl);
use PDL::IO::CSV ':all';

# Header set to the first row following https://github.com/kmx/pdl-io-csv
# Sep_char set to the tab
my $data = rcsv2D('foo.tsv', {text2bad => 1, header => 1, sep_char => "\t"});

print $data;

打印的矩阵是错误的,因为它在标题后缺少带有数字的第一行:

[
 [ 2  3  4  5]
 [ 7  8  9 10]
 [ 6  5  4  3]
 [10  6  8  7]
]

我将标题值更改为“自动”,它应该跳过所有列中具有非数字值的行:

my $data = rcsv2D('foo.tsv', {text2bad => 1, header => 'auto', sep_char => "\t"});

现在我收到一个警告,但矩阵看起来没问题:

Argument "auto" isn't numeric in foreach loop entry at C:/sw/pdl/perl/vendor/lib/PDL/IO/CSV.pm line 335, <DATA> line 207.
[
 [ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [ 7  6  5  4  3]
 [ 4 10  6  8  7]
]

我不明白为什么生成的矩阵会有所不同,以及为什么通过使用header => 1将 header 设置为第一行会得到错误的结果?

4

2 回答 2

2

这似乎是在 0.011 中修复的错误。

0.011   2019/12/04
        - fix: header option eats extra line #2
        - fix: cpantesters failure on long-double perls

使用 0.011,您的代码可以正常工作。

use strict;
use warnings;

use PDL::IO::CSV ':all';

my $data = rcsv2D('foo.tsv', {text2bad => 1, header => 1, sep_char => "\t"});
print $data;
$ perl -e'
   CORE::say join "\t", @$_
      for
         [qw( a  b  c  d  )],
         #    -- -- -- --
         [qw(  1  6  7  4 )],
         [qw(  2  7  6 10 )],
         [qw(  3  8  5  6 )],
         [qw(  4  9  4  8 )],
         [qw(  5 10  3  7 )];
' >foo.tsv

$ perl a.pl

[
 [ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [ 7  6  5  4  3]
 [ 4 10  6  8  7]
]

(请注意,header=>'auto'不支持,并且在发出您报告的警告rcsv2D后被视为。)header=>0

于 2020-01-20T18:50:07.340 回答
1

我发现我有0.010一个PDL::IO::CSV. 从更改文件看来,这个版本有一个错误,因为标题吃了额外的行。这在 0.011 版中已修复:

0.011   2019/12/04
        - fix: header option eats extra line #2
        - fix: cpantesters failure on long-double perls

编辑:我独立找到了一个解决方案,但 ikegami 的答案更有用,因为它解释了header => 'auto'.

于 2020-01-20T19:25:38.913 回答