如何将前导“0x”的混合双精度和十六进制元胞数组转换为二维双精度数组?

How to convert cell array of mixed doubles and hexadecimals with leading "0x" to 2D array of doubles?

我的objective是将包含数字列和十六进制列的混合的制表符分隔数据集解析为双精度矩阵,其中所有值都已转换为浮点数。

我在 Matlab 工作。我有一个包含数字列和十六进制列的混合的 tab-separated 文件,例如:

 A | B | C |     D
---|---|---|-----------
0x3|  1|  2| 0x118c0832
---|---|---|-----------
0x3|  3|  4| 0x118c0832
---|---|---|-----------
0x3|  5|  6| 0x118c0832
---|---|---|-----------
0x3|  7|  8| 0x118c0832

为了解析数据,我像这样使用 textscan() 函数(为简单起见,我们将跳过过去提取 headers 并假装文件从第 2 行开始):

fileID = fopen('data.dat');
formatString = '%s %f %f %s';
data = textscan(fileID,formatString);

注:textscan()不接受十六进制转换字符,%x.

此时我剩下一个 1x4 元胞数组 data,其中 data{1,3} 对应于包含 C 列内容的 4x1 元胞数组,即: data{1,3} == {2; 4; 6; 8}.

一旦所有值都是数字,一个简单的 data = cell2mat(data) 将我的数据转换为所需的 4x4 数组;但是,由于前导 '0x'.

,我正在努力寻找将十六进制单元格转换为浮点数的最简单和最快的方法

我曾尝试使用 regexp()hex2dec() 的组合来组合一些东西,但这通常涉及创建越来越多的元胞数组,因此任何解决方案都显得很复杂。

有什么想法吗?

您可以简单地 trim 关闭所有 0x 值并使用 lambda 表达式 (anonymous function) 转换为十六进制,其中 cellfun.

fileID = fopen('data.dat');
formatString = '%s %f %f %s';
data = textscan(fileID,formatString);

f = @(x) hex2num(x(3:end));

data{1} = cellfun(f, data{1});
data{4} = cellfun(f, data{4});

假设我们手头有第 4 列并将其命名为 dummyStr:

dummyStr = {'0x218c0832','0x138c0832','0x518c0832','0x318c5832'};

您可以使用 regexprep or strrep 删除 0x 标签:

dummyStr = regexprep(dummyStr,'0x',''); 
floatNums = hex2num(dummyStr );

您可以像这样删除对 textscan 的调用中的 0x

fileID = fopen('data.dat');
formatString = '0x%s %f %f 0x%s';
data = textscan(fileID,formatString);

然后用hex2dec (for integer results) or hex2num转换列(对于双精度浮点结果):

data{1} = hex2dec(data{1});
data{4} = hex2dec(data{4});
data = [data{:}];

结果:

data =

           3           1           2   294389810
           3           3           4   294389810
           3           5           6   294389810
           3           7           8   294389810

显然这只适用于 Octave,但如果您使用的是 Octave,那就太好了。 ;)


您可以在不 regex 或去掉 0x 前缀的情况下执行此操作。 str2double 将以 0x 开头的字符串解析为十六进制数并进行相应的转换:

fileID = fopen('data.dat');
formatString = '%s %f %f %s';
data = textscan(fileID,formatString)
fclose(fileID);

data =
{
  [1,1] =
  {
    [1,1] = 0x3
    [2,1] = 0x3
  }
  [1,2] =

     1
     3

  [1,3] =

     2
     4

  [1,4] =
  {
    [1,1] = 0x118c0832
    [2,1] = 0x118c0832
  }
}

data{1} = str2double(data{1});
data{4} = str2double(data{4});

结果:

data =
{
  [1,1] =

     3
     3

  [1,2] =

     1
     3

  [1,3] =

     2
     4

  [1,4] =

     294389810
     294389810

}