performance - 高效地从 matlab 编写 CSV 文件
问题描述
我有 3 个要写入 csv 文件的数组:
dates_array - T x 1
matlab 序列日期向量;
观察 -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);
现在我只需要弄清楚如何将这三列放在一起。
解决方案
我设法将计算机上的执行时间从大约 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);
推荐阅读
- python - 如何循环 BeautifulSoup 的 URL 输出?
- common-lisp - set-dispatch-macro-character 的完整文档在哪里?
- swift - Swift 使用 Delegate 刷新 Tableview
- reactjs - 如何使用不同的 React.render() 函数在组件之间共享数据
- scrapy - Scrapy KeyError(f"{self.__class__.__name__} 不支持字段:{key}"
- html - 在单独的行中显示两个 td
- mongodb - Golang 中的聚合 Mongodb
- java - 如何动态更改 JComboBox 中的项目数
- xamarin.ios - [iOS][Xamarin.UITests]:Xamarin.UITests 无法通过 Wifi 检测到真正的 iPhone
- html - Bootstrap Alert 无法在我的 localhost 网页上运行