【问题标题】:Mixed Data Types Matlab Tables混合数据类型 Matlab 表
【发布时间】:2016-03-14 16:12:23
【问题描述】:

我希望对以下数据使用makeValidName 函数:

Id  Val Random          Desc
a   1.1 0.036835624 Bread Cheese
b   2.2 0.020442492 Fish Bread
c   -3.3    0.020050676 Cheese Fish
d   #N/A    0.017619332 Bread Cheese
e   -5.4    0.014973153 Fish Bread
f   6.6 0.014648887 Cheese Fish
g   -7.6    0.014071844 Bread Cheese
h   8   0.014013118 Fish Bread

但是,当我导入表格(使用 readtable 从 xlsx 读取)时,它看起来像这样:

输入数据 =

 Id             Val              Random          Desc     
____    ____________________    ________    ______________

'a '    '1.1'                   0.036836    'Bread Cheese'
'b'     '2.2'                   0.020442    'Fish Bread'  
'c'     '-3.3'                  0.020051    'Cheese Fish' 
'd'     'ActiveX VT_ERROR: '    0.017619    'Bread Cheese'
'e'     '-5.4'                  0.014973    'Fish Bread'  
'f'     '6.6'                   0.014649    'Cheese Fish' 
'g'     '-7.6'                  0.014072    'Bread Cheese'
'h'     '8'                     0.014013    'Fish Bread'  

如何防止它将Val 中的条目从数字转换为字符串?这使得无法使用makeValidName。我需要在所有行和列中应用makeValidName,因为表非常大,单独命名适当的列是不可行的。那么实现这一目标的最优雅的方式是什么?

当前代码:

varnames = inputData.Properties.VariableNames;
for ii = 1:length(varnames)

inputData.(varnames{ii})= matlab.lang.makeValidName(inputData.(varnames{ii}));

end

产生错误:

使用 matlab.lang.makeValidName 时出错(第 72 行)第一个输入必须是 字符串或字符串向量元胞数组。

并在Val等列中产生不良结果:

输入数据 =

Id            Val             Random         Desc     
___    __________________    ________    _____________

'a'    'x1_1'                0.036836    'BreadCheese'
'b'    'x2_2'                0.020442    'FishBread'  
'c'    'x_3_3'               0.020051    'CheeseFish' 
'd'    'ActiveXVT_ERROR_'    0.017619    'BreadCheese'
'e'    'x_5_4'               0.014973    'FishBread'  
'f'    'x6_6'                0.014649    'CheeseFish' 
'g'    'x_7_6'               0.014072    'BreadCheese'
'h'    'x8'                  0.014013    'FishBread'

【问题讨论】:

  • 您确定您了解makeValidName 的用途吗? Val 列显示的行为与函数的行为一致。
  • 是的。我希望它能够做到这一点,只是我需要它只为非数字条目做到这一点。由于#NA readtable 已将整个 Val 列转换为字符串,即使除一个之外的所有条目都是数字。这导致数字在makeValideName 下被进一步转换。所以理想情况下 readtable 需要正确区分数字或字符串列,或者我需要在导入后转换/清理数据

标签: matlab data-cleaning matlab-table


【解决方案1】:

因为在中间使用 Excel 似乎更让人头疼。我建议使用basic 模式,这将减轻一些解析错误。

来自the documentation

basic 模式是没有 Excel for Windows 的系统的默认模式。在 basic模式,readtable

  • 仅读取 XLS、XLSX、XLSM、XLTX 和 XLTM 文件。
  • 读取 XLS 文件时不支持 'Range' 名称-值对组参数。
  • 将所有日期作为 Excel 序列日期编号导入。 Excel 序列日期编号使用与 MATLAB® 日期编号不同的参考日期。

这允许我们利用 TreatAsEmpty 名称-值对参数,因为它会正确解析数字列。

inputData = readtable('test.xlsx', 'Basic', 1, 'TreatAsEmpty', '#N/A');

示例案例的返回值:

inputData = 

    Id     Val      Random          Desc     
    ___    ____    ________    ______________

    'a'     1.1    0.036836    'Bread Cheese'
    'b'     2.2    0.020442    'Fish Bread'  
    'c'    -3.3    0.020051    'Cheese Fish' 
    'd'     NaN    0.017619    'Bread Cheese'
    'e'    -5.4    0.014973    'Fish Bread'  
    'f'     6.6    0.014649    'Cheese Fish' 
    'g'    -7.6    0.014072    'Bread Cheese'
    'h'       8    0.014013    'Fish Bread'

理论上这应该意味着数字数据列是double 数组,而字符串保留在cell 数组中。因此,要使用matlab.lang.makeValidName,您可以使用iscell 测试每一列,看看它是否是一个元胞数组:

varnames = inputData.Properties.VariableNames;
for ii = 1:length(varnames)
    if iscell(inputData.(varnames{ii}))
        % If they're strings they're in a cell array
        inputData.(varnames{ii})= matlab.lang.makeValidName(inputData.(varnames{ii}));
    end
end

返回:

inputData = 

    Id     Val      Random         Desc     
    ___    ____    ________    _____________

    'a'     1.1    0.036836    'BreadCheese'
    'b'     2.2    0.020442    'FishBread'  
    'c'    -3.3    0.020051    'CheeseFish' 
    'd'     NaN    0.017619    'BreadCheese'
    'e'    -5.4    0.014973    'FishBread'  
    'f'     6.6    0.014649    'CheeseFish' 
    'g'    -7.6    0.014072    'BreadCheese'
    'h'       8    0.014013    'FishBread'  

【讨论】:

  • 不错的解决方案。效果很好。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多