Ответ 1
textread
позволяет указать разделитель - он чтит аргументы свойства strread
. Следующий код работал у меня:
[A,B,C] = textread( 'test.dat', '%s %d %d' ,'delimiter' , ',' ,1 )
Я пытаюсь прочитать текстовый файл, содержащий цифры и строки, используя Octave. Формат файла выглядит примерно так:
A B C
10 100
b 20 200
c 30 300
d 40 400
e 50 500
но разделителем может быть пробел, табуляция, запятая или точка с запятой. Функция textread отлично работает, если разделителем является пробел/табуляция:
[A,B,C] = textread ('test.dat','%s %d %d','headerlines',1)
Однако это не работает, если разделителем является запятая/точка с запятой. Я попытался использовать dklmread:
dlmread ('test.dat',';',1,0)
но это не работает, потому что первый столбец является строкой. В принципе, с textread я не могу указать разделитель и с dlmread я не могу указать формат первого столбца. Не с версиями этих функций в Октаве, по крайней мере. Кто-нибудь когда-либо сталкивался с этой проблемой раньше?
textread
позволяет указать разделитель - он чтит аргументы свойства strread
. Следующий код работал у меня:
[A,B,C] = textread( 'test.dat', '%s %d %d' ,'delimiter' , ',' ,1 )
Я не мог найти простой способ сделать это сейчас в Octave. Вы можете использовать fopen()
для прокрутки файла и вручную извлечь данные. Я написал функцию, которая будет делать это по произвольным данным:
function varargout = coltextread(fname, delim)
% Initialize the variable output argument
varargout = cell(nargout, 1);
% Initialize elements of the cell array to nested cell arrays
% This syntax is due to {:} producing a comma-separated
[varargout{:}] = deal(cell());
fid = fopen(fname, 'r');
while true
% Get the current line
ln = fgetl(fid);
% Stop if EOF
if ln == -1
break;
endif
% Split the line string into components and parse numbers
elems = strsplit(ln, delim);
nums = str2double(elems);
nans = isnan(nums);
% Special case of all strings (header line)
if all(nans)
continue;
endif
% Find the indices of the NaNs
% (i.e. the indices of the strings in the original data)
idxnans = find(nans);
% Assign each corresponding element in the current line
% into the corresponding cell array of varargout
for i = 1:nargout
% Detect if the current index is a string or a num
if any(ismember(idxnans, i))
varargout{i}{end+1} = elems{i};
else
varargout{i}{end+1} = nums(i);
endif
endfor
endwhile
endfunction
Он принимает два аргумента: имя файла и разделитель. Функция определяется количеством возвращаемых переменных, которые заданы, поэтому, например, [A B C] = coltextread('data.txt', ';');
попытается проанализировать три разных элемента данных из каждой строки в файле, а A = coltextread('data.txt', ';');
будет анализировать только первые элементы. Если возвратная переменная не указана, то функция ничего не вернет.
Функция игнорирует строки, имеющие все строки (например, заголовок "A B C" ). Просто удалите раздел if all(nans)...
, если хотите все.
По умолчанию "столбцы" возвращаются как массивы ячеек, хотя числа внутри этих массивов являются фактически преобразованными числами, а не строками. Если вы знаете, что массив ячеек содержит только числа, вы можете легко преобразовать его в вектор-столбец с помощью: cell2mat(A)'
.