我试图从数据中Matlab的将被其他应用程序可以理解的格式导出......对,我需要改变NaN,Inf并-Inf串(即Matlab的打印默认情况下,这样的值)//m,//inf+和//Inf-.
一般来说,我知道如何实现这一目标.我在询问如何(以及是否可能)在Matlab中利用一个特定的东西.实际问题位于最后一段.
我尝试过两种方法(代码如下).
sprintf()的数据和strrep()输出.这是以逐行方式完成的,以节省内存.该解决方案的时间比简单多出近10倍fprintf().优点是它具有低内存开销.Run Code Online (Sandbox Code Playgroud)rows = 50000 cols = 40 data = rand(rows, cols); % generate random matrix data([1 3 8]) = NaN; % insert some NaN values data([5 6 14]) = Inf; % insert some Inf values data([4 2 12]) = -Inf; % insert some -Inf values fid = fopen('data.txt', 'w'); %output file %% 0) Write data using default fprintf format = repmat('%g ', 1, cols); tic fprintf(fid, [format '\n'], data'); toc %% 1) Using strrep, writing line by line fprintf(fid, '\n'); tic for i = 1:rows fprintf(fid, '%s\n', strrep(strrep(strrep(sprintf(format, data(i, :)), 'NaN', '//m'), '-Inf', '//inf-'), 'Inf', '//inf+')); end toc %% 2) Using strrep, writing all at once fprintf(fid, '\n'); format = [format '\n']; tic fprintf(fid, '%s\n', strrep(strrep(strrep(sprintf(format, data'), 'NaN', '//m'), '-Inf', '//inf-'), 'Inf', '//inf+')); toc
经过的时间是1.651089秒.%Regular fprintf()
经过的时间是11.529552秒.%选项1
经过的时间是2.305582秒.%选项2
现在问题......
与简单相比,我对使用我的解决方案所耗费的内存开销和时间不满意fprintf().
我的理由是,'NaN','Inf'和'-Inf'字符串保存在某个变量里面简单的数据*printf()或*2str()执行.有没有办法在运行时更改它们的值?
例如在C#中,我会在这里更改System.Globalization.CultureInfo.NumberFormat.NaNSymbol等等.
在评论中提到的有限情况下,许多(未知,每个数据集发生变化)列可能完全是NaN(或Inf等),但没有不需要的NaN值,否则,另一种可能性是检查第一行数据,组装\\m直接写入字符串的格式字符串,并在告诉fprintf忽略包含或其他不需要的值的列时使用它NaN。
y = ~isnan(data(1,:)); % find all non-NaN
format = sprintf('%d ',y); % print a 1/0 string
format = strrep(format,'1','%g');
format = strrep(format,'0','//m');
fid = fopen('data.txt', 'w');
fprintf(fid, [format '\n'], data(:,y)'); %pass only the non-NaN data
fclose(fid);
Run Code Online (Sandbox Code Playgroud)
通过我对两列的检查,NaN这fprintf与您的“常规”几乎相同fprintf,并且比循环更快 - 不考虑生成的初始化步骤format。如果您还必须考虑 +/- ,那么将其设置为自动生成格式字符串会更麻烦Inf,但当然是可能的。可能还有一种更清洁的生产方式format。
怎么运行的:
您可以传递数据的子集,也可以将任何您喜欢的文本插入到格式字符串中,因此,如果每行在同一位置都有相同的所需“文本”(在本例中为NaN列和我们所需的“文本”替换) NaN"),我们可以将我们想要的文本放在该位置,然后fprintf首先不将数据的这些部分传递给。在命令行上尝试的更简单的示例:
x = magic(5);
x(:,3)=NaN
sprintf('%d %d ihatethrees %d %d \n',x(:,[1,2,4,5])');
Run Code Online (Sandbox Code Playgroud)