【问题标题】:Read matrix in matlab from file saved in "stdout" format从以“stdout”格式保存的文件中读取matlab中的矩阵
【发布时间】:2014-05-21 23:58:40
【问题描述】:

我有一个包含大矩阵打印输出的文件,其格式与打印到 MATLAB 控制台时的格式相同 - 即文件以

开头
dum =

 Columns 1 through 11:

   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000

并一直这样下去,直到打印出整个矩阵。我可以使用例如计算出一些关于矩阵的事情。 grepwc,所以不是完全未知,但是如果没有这些工具和一些手动计算,我就没有元数据。

有没有比使用fscan 解析文件更简洁的方法将此矩阵读入 MATLAB?

【问题讨论】:

  • 看看 dlmread 或 textscan。

标签: matlab io


【解决方案1】:

在查看了 MATLAB 中的文件读取实用程序后,我决定我不想使用其中的任何一个,而是使用了一个小的 shell 脚本来获取原始文件并以常规 ASCII 格式重新编写它,我可以在 MATLAB 中使用 load newfile 加载。

完整的脚本(不同部分的解释如下):

for n in `grep -e 'Col' stupiddump.txt | sed 's/ Columns [0-9]* through \([0-9]*\):/\1/'`; do  
    pcregrep --multiline "$n:\\n\\s*\\n([\\d\\.\\s]+)" stupiddump.txt | sed '/\s*Colu.*/d' | sed '/^$/d' > "$n.out"; 
done
paste *.out > betterdump.txt && rm *.out

好的,这是很多正则表达式。我会第一个承认这不是一个优雅的解决方案,但它确实有效。

What's really going on here?

第一个grep 取出所有写着“Columns X to Y:”的行

$ grep -e 'Col' stupiddump.txt
 Columns 1 through 11:
 Columns 12 through 22:
 Columns 23 through 33:
 Columns 34 through 44:
 Columns 45 through 55:
 Columns 56 through 65:

sed 中使用的下一个正则表达式会删除每一行上除了最后一个数字之外的所有内容:

$ grep -e 'Col' stupiddump.txt | sed 's/ Columns [0-9]* through \([0-9]*\):/\1/'
11
22
33
44
55
65

这允许我们一次只搜索这些集合中的一个。所以我们把那个漂亮的小脚本用反引号包裹起来,然后循环遍历结果:

$ for n in `grep -e 'Col' stupiddump.txt | sed 's/ Columns [0-9]* through \([0-9]*\):/\1/'`; do
    echo "The number is $n";
  end
The number is 11
The number is 22
The number is 33
The number is 44
The number is 55
The number is 65

循环中的第一个命令挑选出数据文件的相关部分:

$ pcregrep --multiline "$n:\\n\\s*\\n([\\d\\.\\s]+)" stupiddump.txt
 Columns 1 through 11:

   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
etc...
   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000

 Columns 12 through 22:

我必须使用pcegrep 才能使用多行正则表达式。我们通过管道传送到的 seds 将周围的文本行替换为空,因此唯一剩下的就是实际的矩阵内容:

$ pcregrep --multiline "$n:\\n\\s*\\n([\\d\\.\\s]+)" stupiddump.txt | sed '/\s*Colu.*/d' | sed '/^$/d'
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000   0.10000
etc...
   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000   1.10000

我们将此输出重定向到一个名为"$n.out" 的文件中,这样当循环完成时,我们就有一堆名为11.out22.out 等的文件,其中包含相应的列集。

最后,我们使用paste 水平连接这些文件,并删除临时文件。在这种情况下我很幸运并且不必担心排序,因为数字和词汇排序是相同的,但是如果您的文件的列号不具有相同的位数,您可能必须这样做有点聪明。

$ paste *.out > betterdump.txt && rm *.out

现在,betterdump.txt 的格式与我首先键入 save -ascii A 来保存矩阵时的格式大致相同,因此我可以使用 load 轻松读取它。

【讨论】:

    【解决方案2】:

    您可以采取以下步骤将此类数据导入 matlab,而无需过多挖掘可用函数:

    1. 在 matlab 中右键单击文件
    2. 点击导入数据
    3. 选择矩阵
    4. 设置范围 A3:K6(或文件结束位置)
    5. 点击导入,或点击生成代码

    从这里你会得到这样的代码:

    filename = 'U:\MATLAB\dum.txt';
    delimiter = ' ';
    startRow = 3;
    formatSpec = '%f%f%f%f%f%f%f%f%f%f%f%[^\n\r]';
    fileID = fopen(filename,'r');
    textscan(fileID, '%[^\n\r]', startRow-1, 'ReturnOnError', false);
    dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'ReturnOnError', false);
    fclose(fileID);
    dum = [dataArray{1:end-1}];
    clearvars filename delimiter startRow formatSpec fileID dataArray ans;
    

    使用此代码或对其进行调整以使其更方便应该不难。

    【讨论】:

    • 即使矩阵的列数超过了一个“集合”中的列数,这项工作是否有效,即Columns 12 through 22: 等还有另一行?
    • @TomasLycken 在这种情况下,您可能希望先将其作为元胞数组(而不是矩阵)导入,然后再进行一些后期处理。
    猜你喜欢
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多