首页 > 解决方案 > 高效地从 matlab 编写 CSV 文件

问题描述

我有 3 个要写入 csv 文件的数组:

dates_array - T x 1matlab 序列日期向量;

观察 -T x N数值数据数组;

string_array -N x 1字符串向量

我想以面板格式将所有内容放入单元格数组中。我可以为此做一个 for 循环。但是当 T 和 N 非常大时,这是非常低效的;

clear all
clc

% Generate Data

T = 1000;
N = 100;

dates_array = 737791:1:737791+T-1;
dates_array = dates_array';
observations = rand(T,N);
string_array = string(char(randi([33 126],N,10)));

% Put in panel format
count = 1;
for i = 1:N
for j=1:T

    out_for_csv{count,1} = {datestr(dates_array(j,1))};
    out_for_csv(count,2) = {observations(j,i)};
    out_for_csv(count,3) = {string_array(i,1)};
    count = count + 1;
end
end


Tab = cell2table(out_for_csv);
writetable(Tab,'myDataFile.csv')

需要有一种更好的方法来代替循环。我确实尝试了一些东西,但总是无法将所有东西放在out_for_csv矩阵上。

例如,获取三列向量的一种有效方法是:

column1 = repmat(datestr(dates_array(j,1)),N,1);
column2 = observations(:);
column3 = repelem(string_array,T,1);

现在我只需要弄清楚如何将这三列放在一起。

标签: performancematlabcsv

解决方案


我设法将计算机上的执行时间从大约 21 秒缩短到 1.5 秒,速度提高了 14 倍!真正让事情进展得很快的是在内存中构建一个大字符矩阵,然后用一个fprintf命令写出来。

我对代码所做的一些小改动是为随机数生成器设置种子,这样我就可以获得一致的随机数,这样我就可以将原始代码与我的新代码进行比较。我还将随机字符串限制为仅是大写字母,因为原始代码有时会选择逗号,这会导致在将输出文件读入 Excel 时列数不一致。

一件棘手的事情是,当您使用 写出字符 maxtrix 时fprintf,您需要将其转置,因为fprintf首先要在每一列下工作。

这是代码:

T = 1000;
N = 100;

dates_array = 737791 + (0:(T-1))';
dates_array = datestr(dates_array);
% Add a comma after the dates
dates_array = [dates_array, repmat(',', T, 1)];
% Replicate the dates N times
dates_array = repmat(dates_array, N, 1);

% Seed the randon number generator to get consistent values so comparisons between versions can be made
rng(0)
observations = rand(T, N);
% convert from a matrix to a column
observations = reshape(observations, T*N, 1);
% Convert from numbers to characters
observations = num2str(observations, 5);
% Add a comma after the observations
observations = [observations, repmat(',', T*N, 1)];

% Make the matrix of strings
string_array = char(randi([65 90], 1, N * 10));
% Replicate T times
string_array = repmat(string_array, T, 1);
% Turn matrix of 10-char strings into a vector of 10-char strings
string_array = reshape(string_array, N * T, 10);

% Join the date, observations, strings, and carriage return
out = [dates_array, observations, string_array, repmat(newline, T*N, 1)];

title_row = 'col1,col2,col3';
num_extra_commas = size(out, 2) - length(title_row) - 1;
title_row = [title_row, repmat(',', 1, num_extra_commas), newline];
out = [title_row; out];

fid = fopen('myDataFileb.csv', 'wt');
fprintf(fid, '%s', out');
fclose(fid);

推荐阅读