【问题标题】:Saving and formatting text file with Matlab使用 Matlab 保存和格式化文本文件
【发布时间】:2015-03-29 21:40:36
【问题描述】:

我有一个由两行组成的文本文件,格式如下:

"27 feb 2015","28 feb 2015","1 mar 2015",...
"1","2","3","4",...

如何将这些值保存在 两个数组 中并使用 MATLAB 绘制它们?

编辑

第一行包含引号之间的字符串,第二行包含引号之间的整数。

【问题讨论】:

  • 您的文本文件是否也包含引号,或者它真的只是一个类似于:27 feb 2015, 28 feb 2015, 1 mar 2015, ..., <newline> 1, 2, 3, 4, ... 的 CSV 文件?如果您的文本文件不包含格式字符串(即%s, %d),请将它们从您的问题中删除。这真的很令人困惑,因为我不知道格式化字符串是否是文本文件的一部分,或者您是否将它们放在那里以举例说明每个条目每行的格式。
  • 第一行包含引号之间的字符串和"之间的第二个整数
  • OK,所以""之间有字符串,用逗号隔开,第二行""之间有整数?
  • 是的,完全正确。谢谢编辑
  • 没问题。让我写一个答案。其实很简单。

标签: matlab csv text formatting


【解决方案1】:

最简单的方法是将这两行作为单独的字符串读取,然后使用正则表达式自己解析数据。然后从那里,您可以将每个日期转换为日期编号,绘制日期,如果需要,您可以在水平轴上绘制实际日期。

使用fopen 打开文件后,最好使用两次fgetl。假设您的文件存储在名为 data.txt 的文件中,并确保将工作目录设置为存储文本文件的位置,请先执行以下操作:

fid = fopen('data.txt', 'r');
first_row = fgetl(fid);
second_row = fgetl(fid);
fclose(fid);

first_rowsecond_row 将包含包含文本文件第一行和第二行的字符数组。我们打开文件,读入前两行,然后用fclose 关闭文件。接下来,我们可以使用regular expressions 轻松拆分日期。正则表达式尝试在字符串中查找模式。具体来说,我们有一个定义明确的模式,您希望从中取出引号字符之间的字符串。具体来说,您需要一堆数字、字母或空格字符。使用regexp 来帮助您做到这一点。您可以通过以下代码提取日期:

dates = regexp(first_row, '\"([\w+ ]+)\",', 'tokens');

第一个元素是您要解析的字符串,第二个元素是您要查找的模式。具体来说,模式是\"([\w+ ]+)\"。这个看起来很糟糕的陈述意味着您正在寻找以"开头的模式,有一大堆字符后跟空格,然后我们以另一个"结尾。我将() 放在引号之间,因为我不希望在输出中出现引号字符。我使用'tokens' 标志,因为这意味着我想获取() 中的实际字符。当我运行上述行并显示输出时,我们得到:

>> celldisp(dates)

dates{1}{1} =

27 feb 2015


dates{2}{1} =

28 feb 2015


dates{3}{1} =

1 mar 2015

我们对第二行做同样的事情,但我们只寻找数字:

numbers = regexp(second_row, '\"(\d+)\",', 'tokens');

这里,我们要查找的模式是\"(\d+)\",这意味着我们要查找引号之间的数字序列。显示此输出给出:

>> celldisp(numbers);

numbers{1}{1} =

1


numbers{2}{1} =

2


numbers{3}{1} =

3


numbers{4}{1} =

4

因为numbers 是一个元胞数组,所以使用cellfun 将元素转换为数值数组:

numbers = cellfun(@(x) str2double(x{1}), numbers);

这会遍历单元格数组中的每个元素,这是一个嵌套单元格,我们将数字转换为实际数值。请记住,这些仍然是字符。

现在,您只需将日期转换为数字,进行我们的绘图,如果需要,您可以将日期数字转换为实际日期。所以:

dates = cellfun(@(x) x{1}, dates, 'uni', 0);
datenums = datenum(dates, 'dd mmm yyyy');

dates 原本是一个嵌套的字符串元胞数组,因此我们需要将字符串解包,以便将每个字符串放入一个元胞数组中。 datenum 将日期字符串转换为物理日期数字。您提供了一个格式化字符串,在您的情况下,它是 dd mm yyyy

现在,您所要做的就是绘制这些东西:

plot(datenums, numbers);
set(gca, 'XTick', datenums);
set(gca, 'XTickLabel', dates);

第一行绘制了我们的东西。第二行和第三行重命名x-轴,这样我们就可以用日期代替数值了。

我制作了一个示例文本文件,其中包含:

"27 feb 2015","28 feb 2015","1 mar 2015","2 mar 2015",
"1","2","3","4",

当我使用上面的示例时,通过上面的代码,我们得到:


为了您的复制和粘贴乐趣,完整的代码如下所示:

fid = fopen('data.txt', 'r');
first_row = fgetl(fid);
second_row = fgetl(fid);
fclose(fid);

dates = regexp(first_row, '\"([\w+ ]+)\",', 'tokens');
dates = cellfun(@(x) x{1}, dates, 'uni', 0);

numbers = regexp(second_row, '\"(\d+)\",', 'tokens');
numbers = cellfun(@(x) str2double(x{1}), numbers);

datenums = datenum(dates, 'dd mmm yyyy');

plot(datenums, numbers);
set(gca, 'XTick', datenums);
set(gca, 'XTickLabel', dates);

【讨论】:

  • 有史以来最好的答案!你应该得到 +2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 2015-01-16
  • 2013-10-24
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多