在Matlab中更改fprintf()的默认NaN表示

Kup*_*pto 5 matlab printf

我试图从数据中Matlab的将被其他应用程序可以理解的格式导出......对,我需要改变NaN,Inf-Inf串(即Matlab的打印默认情况下,这样的值)//m,//inf+//Inf-.

一般来说,我知道如何实现这一目标.我在询问如何(以及是否可能)在Matlab中利用一个特定的东西.实际问题位于最后一段.

我尝试过两种方法(代码如下).

  1. 使用sprintf()数据strrep()输出.这是以逐行方式完成的,以节省内存.该解决方案的时间比简单多出近10倍fprintf().优点是它具有低内存开销.
  2. 与选项1相同,但翻译是在整个数据上完成的.此解决方案更快,但容易出现内存不足异常.我对这种方法的问题是我不想不必要地复制数据.

码:

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  
Run Code Online (Sandbox Code Playgroud)

输出:

经过的时间是1.651089秒.%Regular fprintf()
经过的时间是11.529552秒.%选项1
经过的时间是2.305582秒.%选项2

现在问题......

与简单相比,我对使用我的解决方案所耗费的内存开销和时间不满意fprintf().
我的理由是,'NaN','Inf''-Inf'字符串保存在某个变量里面简单的数据*printf()*2str()执行.有没有办法在运行时更改它们的值?
例如在C#中,我会在这里更改System.Globalization.CultureInfo.NumberFormat.NaNSymbol等等.

nkj*_*kjt 1

在评论中提到的有限情况下,许多(未知,每个数据集发生变化)列可能完全是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)

通过我对两列的检查,NaNfprintf与您的“常规”几乎相同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)