gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 19:47:32 25 4
gpt4 key购买 nike

我正在尝试以其他应用程序可以理解的格式从 Matlab 导出数据... 为此,我需要更改 NaNInf-Inf 字符串(Matlab 默认打印此类值)到 //m//inf+//Inf-.

总的来说,我确实知道如何做到这一点。我在问如何(以及是否可能)在 Matlab 中利用一个特定的东西。实际问题位于最后一段。

我尝试了两种方法(代码如下)。

  1. 数据strrep() 输出使用sprintf()。这是以逐行方式完成的,以节省内存。此解决方案比简单的 fprintf() 花费的时间几乎多 10 倍。优点是内存开销小。
  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

输出:

Elapsed time is 1.651089 seconds. % Regular fprintf()
Elapsed time is 11.529552 seconds. % Option 1
Elapsed time is 2.305582 seconds. % Option 2

现在问题...

与简单的 fprintf() 相比,我对使用我的解决方案的内存开销和时间损失不满意。
我的理由是 'NaN''Inf''-Inf' 字符串是保存在 *printf()*2str() 实现。有什么办法可以在运行时改变它们的值吗?
例如,在 C# 中,我会更改 System.Globalization.CultureInfo.NumberFormat.NaNSymbol 等,如 here 所述。 .

最佳答案

在评论中提到的有限情况下,许多(未知,根据数据集变化)列可能完全是 NaN(或 Inf 等),但是否则没有不需要的 NaN 值,另一种可能性是检查第一行数据,组装一个直接写入 \\m 字符串的格式字符串,然后使用它 while告诉 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);

通过我对两列 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])');

关于matlab - 在 Matlab 中更改 fprintf() 的默认 NaN 表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25061400/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com