我的目标是将包含数字列和十六进制列混合的制表符分隔数据集解析为双矩阵,其中所有值都已转换为浮点数。
我在Matlab工作。我有一个制表符分隔文件,其中包含数字列和十六进制列的混合,例如:
A | B | C | D
---|---|---|-----------
0x3| 1| 2| 0x118c0832
---|---|---|-----------
0x3| 3| 4| 0x118c0832
---|---|---|-----------
0x3| 5| 6| 0x118c0832
---|---|---|-----------
0x3| 7| 8| 0x118c0832
为了解析数据,我像这样使用textscan()
函数(为简单起见,我们将跳过标题的提取并假装文件从第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()
的组合将某些内容组合在一起,但这通常涉及创建越来越多的单元格数组,因此任何解决方案似乎都很复杂。
有什么想法吗?
答案 0 :(得分:6)
您可以删除textscan
调用中的0x
,如下所示:
fileID = fopen('data.dat');
formatString = '0x%s %f %f 0x%s';
data = textscan(fileID,formatString);
然后使用hex2dec
(对于整数结果)或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
答案 1 :(得分:2)
你可以简单地修剪所有的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});
答案 2 :(得分:2)
我们假设我们手头有第四列,并将其命名为dummyStr
:
dummyStr = {'0x218c0832','0x138c0832','0x518c0832','0x318c5832'};
您可以使用regexprep或strrep删除 0x 标记:
dummyStr = regexprep(dummyStr,'0x','');
floatNums = hex2num(dummyStr );
答案 3 :(得分:2)
显然这只适用于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
}