Octave strread 无法 return 将结果解析为数组(?)
Octave strread can't return parsed results to an array (?)
在 Octave 中,我从磁盘读取非常大的文本文件并解析它们。函数 textread() 做的正是我想要的,除了它的实现方式。查看源代码,textread.m 在尝试解析行之前将整个文本文件拉入内存。如果文本文件很大,它会用文本填充我所有的空闲 RAM (16 GB),然后在解析之前开始保存回磁盘(虚拟内存)。如果我等待足够长的时间,textread() 将完成,但它几乎要花很长时间。
请注意,在解析为浮点值矩阵后,相同的数据很容易装入内存。所以我在中间区域使用 textread(),那里有足够的内存用于浮点数,但没有足够的内存用于与文本相同的数据。
所有这些都是为我的问题做准备,这是关于 strread() 的。我的文本文件中的数据如下所示
0.0647148 -2.0072535 0.5644875 8.6954257
0.1294296 -8.4689583 0.6567095 144.3090450
0.1941444 -9.2658037 -1.0228742 173.8027785
0.2588593 -6.5483359 -1.5767574 90.7337329
0.3235741 -0.7646807 -0.5320896 1.7357120
...等等。文件中没有 header 行或注释。
我编写了一个逐行读取文件的函数,请注意我尝试使用 strread() 解析一行数据的两种方式。
function dest = readPowerSpectrumFile(filename, dest)
% read enough lines to fill destination array
[rows, cols] = size(dest);
fid = fopen(filename, 'r');
for line = 1 : rows
lstr = fgetl(fid);
% this line works, but is very brittle
[dest(line, 1), dest(line, 2), dest(line, 3), dest(line, 4)] = strread(lstr, "%f %f %f %f");
% This line doesn't work. Or anything similar I can think of.
% dest(line, 1:4) = strread(lstr, "%f %f %f %f");
endfor
fclose(fid);
endfunction
有没有一种优雅的方法可以让 strread return 将值解析为数组?否则我每次更改列数时都必须编写一个新函数。
谢谢
如果您输入 fprintf
比其格式规范中更多的值,它将重新应用打印语句,直到用完为止:
>> fprintf("%d %d \n", 1:6)
1 2
3 4
5 6
看来这也适用于 strread
。如果你只指定一个值来读取,但当前行有多个值,它会继续读取它们并将它们添加到一个列向量中。我们需要做的就是将这些值分配给 dest
:
的正确行
function dest = readPowerSpectrumFile(filename, dest)
% read enough lines to fill destination array
[rows, cols] = size(dest);
fid = fopen(filename, 'r');
for line = 1 : rows
lstr = fgetl(fid);
% read all values from current line into column vector
% and store values into row of dest
dest(line,:) = strread(lstr, "%f");
% this will also work since values are assumed to be numeric by default:
% dest(line,:) = strread(lstr);
endfor
fclose(fid);
endfunction
输出:
readPowerSpectrumFile(filename, zeros(5,4))
ans =
6.4715e-02 -2.0073e+00 5.6449e-01 8.6954e+00
1.2943e-01 -8.4690e+00 6.5671e-01 1.4431e+02
1.9414e-01 -9.2658e+00 -1.0229e+00 1.7380e+02
2.5886e-01 -6.5483e+00 -1.5768e+00 9.0734e+01
3.2357e-01 -7.6468e-01 -5.3209e-01 1.7357e+00
您描述的格式是具有浮点值的矩阵。在这种情况下,您可以只使用 load
d = load ("yourfile");
这比任何其他函数都快得多。您可以查看 libinterp/corefcn/ls-mat-ascii.cc 中使用的实现:read_mat_ascii_data
在 Octave 中,我从磁盘读取非常大的文本文件并解析它们。函数 textread() 做的正是我想要的,除了它的实现方式。查看源代码,textread.m 在尝试解析行之前将整个文本文件拉入内存。如果文本文件很大,它会用文本填充我所有的空闲 RAM (16 GB),然后在解析之前开始保存回磁盘(虚拟内存)。如果我等待足够长的时间,textread() 将完成,但它几乎要花很长时间。
请注意,在解析为浮点值矩阵后,相同的数据很容易装入内存。所以我在中间区域使用 textread(),那里有足够的内存用于浮点数,但没有足够的内存用于与文本相同的数据。
所有这些都是为我的问题做准备,这是关于 strread() 的。我的文本文件中的数据如下所示
0.0647148 -2.0072535 0.5644875 8.6954257
0.1294296 -8.4689583 0.6567095 144.3090450
0.1941444 -9.2658037 -1.0228742 173.8027785
0.2588593 -6.5483359 -1.5767574 90.7337329
0.3235741 -0.7646807 -0.5320896 1.7357120
...等等。文件中没有 header 行或注释。
我编写了一个逐行读取文件的函数,请注意我尝试使用 strread() 解析一行数据的两种方式。
function dest = readPowerSpectrumFile(filename, dest)
% read enough lines to fill destination array
[rows, cols] = size(dest);
fid = fopen(filename, 'r');
for line = 1 : rows
lstr = fgetl(fid);
% this line works, but is very brittle
[dest(line, 1), dest(line, 2), dest(line, 3), dest(line, 4)] = strread(lstr, "%f %f %f %f");
% This line doesn't work. Or anything similar I can think of.
% dest(line, 1:4) = strread(lstr, "%f %f %f %f");
endfor
fclose(fid);
endfunction
有没有一种优雅的方法可以让 strread return 将值解析为数组?否则我每次更改列数时都必须编写一个新函数。
谢谢
如果您输入 fprintf
比其格式规范中更多的值,它将重新应用打印语句,直到用完为止:
>> fprintf("%d %d \n", 1:6)
1 2
3 4
5 6
看来这也适用于 strread
。如果你只指定一个值来读取,但当前行有多个值,它会继续读取它们并将它们添加到一个列向量中。我们需要做的就是将这些值分配给 dest
:
function dest = readPowerSpectrumFile(filename, dest)
% read enough lines to fill destination array
[rows, cols] = size(dest);
fid = fopen(filename, 'r');
for line = 1 : rows
lstr = fgetl(fid);
% read all values from current line into column vector
% and store values into row of dest
dest(line,:) = strread(lstr, "%f");
% this will also work since values are assumed to be numeric by default:
% dest(line,:) = strread(lstr);
endfor
fclose(fid);
endfunction
输出:
readPowerSpectrumFile(filename, zeros(5,4))
ans =
6.4715e-02 -2.0073e+00 5.6449e-01 8.6954e+00
1.2943e-01 -8.4690e+00 6.5671e-01 1.4431e+02
1.9414e-01 -9.2658e+00 -1.0229e+00 1.7380e+02
2.5886e-01 -6.5483e+00 -1.5768e+00 9.0734e+01
3.2357e-01 -7.6468e-01 -5.3209e-01 1.7357e+00
您描述的格式是具有浮点值的矩阵。在这种情况下,您可以只使用 load
d = load ("yourfile");
这比任何其他函数都快得多。您可以查看 libinterp/corefcn/ls-mat-ascii.cc 中使用的实现:read_mat_ascii_data