使用 header 从 tsv 文件加载 PDL 矩阵无法按预期工作

Loading PDL matrix from tsv file with header does not work as expected

我有一个 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;

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

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

我将 header 值更改为 'auto',这应该跳过所有列中具有 non-numeric 值的行:

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 设置到第一行 header => 1[= 而得到错误的结果29=] ?

这似乎是一个已在 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]
]

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

我发现我有 PDL::IO::CSV0.010 版本。从 Changes 文件来看,这个版本似乎有一个错误,因为 header 吃掉了额外的行。这已在 0.011 版中修复:

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

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