【问题标题】:Matlab, read multiple 2d arrays from a csv fileMatlab,从 csv 文件中读取多个二维数组
【发布时间】:2012-05-21 18:26:40
【问题描述】:

我有一个 csv 文件,其中包含 4 列但行数不同的二维数组。例如:

2, 354, 23, 101
3, 1023, 43, 454
1, 5463, 45, 7657

4, 543, 543, 654
3, 56, 7654, 344

...

我需要能够导入数据,以便我可以对每个数据块运行操作,但是 csvreaddlmreadtextscan 全部忽略空行。

我似乎无法在任何地方找到解决方案,怎么办?

PS:

可能值得注意的是,上述格式的文件实际上是许多文件的串联,仅包含一个数据块(我不想每次都读取数千个文件)因此之间的空白行块可以更改为任何其他分隔符/标记。这只是通过 python 脚本完成的。

编辑:我的解决方案 - 基于/受以下 petrichor 启发

我用 textscan 替换了 csvread,这样更快。然后我意识到,如果我用 nan 行替换空白行(修改我的 python 脚本),我可以消除对第二个 textscan 慢点的需要。我的代码是:

filename = 'data.csv';
fid = fopen(filename);
allData = cell2mat(textscan(fid,'%f %f %f %f','delimiter',','));
fclose(fid);

nanLines = find(isnan(allData(:,1)))';

iEnd = (nanLines - (1:length(nanLines)));
iStart = [1 (nanLines(1:end-1) - (0:length(nanLines)-2))];
nRows = iEnd - iStart + 1;

allData(nanLines,:)=[];

data = mat2cell(allData, nRows);

计算时间为 0.28 秒(文件只有 103000 行)。我已经接受了 petrichor 的解决方案,因为它确实最好地解决了我最初的问题。

【问题讨论】:

  • 我想一种方法是用 NaN、NaN、NaN、NaN 之类的东西替换空白行,然后在使用 csvread 或类似的东西加载数据后,您可以遍历数据并提取块在matlab中很容易。
  • 我希望避免在导入后循环返回数据,因为(我假设)这只会增加整个过程的时间。另一方面,到目前为止,我发现 textscan 是最快的导入方式?
  • 完全不留下分隔线,而是创建第二个文件,该文件只是新块开始时的行索引,然后使用该文件定义要处理的行范围,而不是创建每个单独的矩阵?
  • 我不知道如何在代码块中整理我的颜色?!
  • 哈哈 - 我也想知道如何正确地做颜色。出于兴趣,你打算用这些数据做什么,你能提供一个例子来说明你将如何使用它吗?我问是因为存储在单元格数组中可能不是最有效的方法......

标签: matlab file-io csv import


【解决方案1】:
filename = 'data.txt';

%# Read all the data
allData = csvread(filename);

%# Compute the empty line indices
fid = fopen(filename);
lines = textscan(fid, '%s', 'Delimiter', '\n');
fclose(fid);
blankLines = find(cellfun('isempty', lines{1}))';

%# Find the indices to separate data into cells from the whole matrix
iEnd = [blankLines - (1:length(blankLines)) size(allData,1)];
iStart = [1 (blankLines - (0:length(blankLines)-1))];
nRows = iEnd - iStart + 1;

%# Put the data into cells
data = mat2cell(allData, nRows)

这为您的数据提供以下信息:

data = 

    [3x4 double]
    [2x4 double]

【讨论】:

  • 感谢 petrichor,一个不错的解决方案。正如我在上面的评论中提到的那样,我希望避免循环返回数据,但您的解决方案提供了一个很好的中间立场。我的实际数据的计时:我发现 csvread 需要 0.46 秒,而使用 textscan 只需要 0.26。因此,当我用 textscan 替换 csvread 时,您的解决方案总共只需要 0.49 秒,这对我来说应该足够快了。我仍然很好奇是否有一个“一步”的方式......非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
  • 2011-12-24
  • 2015-03-19
相关资源
最近更新 更多