Matlab 的“可读表”是否识别列标题?

问题描述

我有以下 CSV 文件,第 1 行带有列标题

Test.csv
--------
Prj,Cap
A,1
A,2
H,4
H,5

我尝试将其读入表格,但无法让 readtable 识别第 1 行的列标题

readtable( 'Test.csv',...
           delimitedTextImportOptions( 'VariableNamesLine',1 ) )

Var1     ExtraVar1
_____    _________
'Prj'     ' Cap'  
'A'       '  1'   
'A'       '  2'   
'H'       '  4'   
'H'       '  5'   

我对 VariableNamesLine 参数有什么误解?

我使用的是 Matlab 2019a。 doc delimitedTextImportOptions 显示它是在 Matlab 2016b 中引入的,而我正在运行 Matlab 2019a。

问题排查步骤

这是 delimitedTextImportOptions 对象:

dtio = delimitedTextImportOptions( 'VariableNamesLine',1)

     DelimitedTextImportOptions with properties:
      Format Properties:
                       Delimiter: {','}
                      Whitespace: '\b\t '
                      LineEnding: {'\n'  '\r'  '\r\n'}
                    CommentStyle: {}
       ConsecutiveDelimitersRule: 'split'
           LeadingDelimitersRule: 'keep'
                   EmptyLineRule: 'skip'
                        Encoding: 'system'
      Replacement Properties:
                     MissingRule: 'fill'
                 ImportErrorRule: 'fill'
                ExtraColumnsRule: 'addvars'
      Variable Import Properties: Set types by name using setvartype
                   VariableNames: {'Var1'}
                   VariableTypes: {'char'}
           SelectedVariableNames: {'Var1'}
                 VariableOptions: Show all 1 VariableOptions
      Access VariableOptions sub-properties using setvaropts/getvaropts
      Location Properties:
                       DataLines: [1 Inf]
               VariableNamesLine: 1
                  RowNamesColumn: 0
               VariableunitsLine: 0
        VariableDescriptionsLine: 0

如果我将 ReadVariableNames 指定为 true,则仅识别 第一标题。它仍然在数据中重复。

readtable( 'Test.csv',dtio,'ReadVariableNames',true )

     Prj     ExtraVar1
    _____    _________
    'Prj'     ' Cap'
    'A'       '  1'
    'A'       '  2'
    'H'       '  4'
    'H'       '  5'

我可以通过明确指定 DataLines 来避免将标题读作数据,但第 2 列标题仍未读取。

dtio = delimitedTextImportOptions( ...
  'VariableNamesLine',1,...
  'DataLines',[2 Inf] );
readtable( 'Test.csv',true )

Prj    ExtraVar1
___    _________
'A'      '  1'
'A'      '  2'
'H'      '  4'
'H'      '  5'

奇怪的是,如果我另外取消设置任何先入为主的 DataLinesVariableNames 规范将被忽略:

dtio = delimitedTextImportOptions( ...
  'VariableNamesLine',[2 Inf],...
   'VariableNames',{} );
readtable( 'Test.csv',true )

    ExtraVar1    ExtraVar2
    _________    _________
     'Prj  '      ' Cap'
     'A    '      '  1'
     'A    '      '  2'
     'H    '      '  4'
     'H    '      '  5'

根据回复中的建议,我尝试了认的 readtable 选项。不幸的是,这并没有将 , 识别为分隔符:

readtable('Test.csv')

Warning: Table variable names were modified to make them valid MATLAB identifiers. The original names are saved in the VariableDescriptions property. 

    Prj    x_     Cap
    ___    ___    ___
    'A'    ','     1 
    'A'    ','     2 
    'H'    ','     4 
    'H'    ','     5 

使用格式字符串有助于识别列标题行,但为字符串列保留分隔符周围的空白:

readtable('Test.csv','Format','%s%u')

      Prj      Cap
    _______    ___
    'A    '     1 
    'A    '     2 
    'H    '     4 
    'H    '     5 

无论 Test.csv 是 Unix 还是 DOS 行结尾,我都得到相同的结果。

我将继续调查、阅读和实验。

附言很奇怪,但是 Matlab Central 的 Matlab Answers 论坛不允许我发布这个问题(来这里之前)。我可以为主题标题输入文本,但无论单击多少,消息正文中都不会出现插入点。使用 Firefox 和 Edge 都会发生这种情况。

解决方法

从 R2020a 开始,您可以直接使用

readtable('Test.csv')

该命令自动指示跳过标题的第一行。每列的数据类型将从数据本身推断出来。

或者,您可以使用命令选项 'Format' 指定每列的数据类型:

readtable('Test.csv','Format','%s%u')

这会将您的第一列读取为字符串,将第二列读取为无符号整数(对于有符号整数,请使用 %i)。