2016-05-26 4 views
1

Я использовал matlab для создания .txt файлов, которые имеют разные 3 столбца, разделенные вкладками (строка, float, float) и различное количество строк.Как импортировать данные из файла в переменные массивы? (Matlab)

Я пытаюсь прочитать каждый из этих трех столбцов данных в 3 разных переменных. Вот мой код:

fileId = fopen('file.txt'); 

% Storing columns from txt file into appropriate compartment data arrays 
compartment_name = textscan(fileId,'%s%*f%*f','Delimiter','\t'); % column of strings 
compartment_length = textscan(fileId,'%*s%f%*f','Delimiter','\t'); % column of doubles 
compartment_diameter = textscan(fileId,'%*s%*f%f','Delimiter','\t'); % column of doubles 

fclose('file.txt'); 

я получить правильные данные для compartment_name (1x1 клеток, содержащих 106x1 клетки (каждая из которых являются строка)), однако оба compartment_length и compartment_diameter возвращает пустой 1x1 ячейка, которая содержит 0x1 двойной.

Любые мысли?

Также - есть ли какой-либо простой способ для преобразования ячеек 1x1 в массив? т.е. для имени_качества, это будет массив строк 1x106?

+0

Я думаю, проблема может заключаться в том, что индикатор положения файла остается в конце файла после вашего первого текстового экрана. Попробуйте 'fseek (fileId, 0, 'bof')', чтобы переместить индикатор обратно в начало файла между чтениями. – jgrant

ответ

1

Поскольку @jgrant отметил in a comment, проблема в том, что вам нужно сбросить индикатор положения файла до начала файла, если вы хотите перечитать части своего файла.

Я не могу понять, почему вы пытаетесь вызвать textscan три раза, причина того, что выход из textscan является клетка точно, что вы можете сделать один вызов к нему, а затем отделить выходные столбцы:

tmpcell = textscan(fileId,'%s%f%f','Delimiter','\t'); % column of strings 

compartment_name = tmpcell{1}; 
compartment_length = tmpcell{2}; 
compartment_diameter = tmpcell{3}; 

% or if you want to be fancy about it: 
%[compartment_name, compartment_length, compartment_diameter] = tmpcell{:}; 

причина, почему я пишу этот ответ ваш Конечная нота:

Кроме того - есть ли простой способ для меня, чтобы преобразовать 1x1 клетки в массив? т.е. для имени_качества, это будет массив строк 1x106?

Это указывает на замешательство в отношении строк в MATLAB. В MATLAB строками являются по существу массивы целых чисел. Вы можете увидеть это для себя, выполняя какой-либо арифметической операции на строку:

>> tmpstring = 'asdf' 

tmpstring = 

asdf 

>> tmpstring*1 

ans = 

    97 115 100 102 

цифры, которые вы видите, являются ASCII представления символов в строке. Это тоже работает наоборот: вы можете создать строку, поместив целые числа в массив. В самом деле, для всех намерений и целей натягивает являются целыми массивами:

>> isequal([97 115 100 102],'asdf') 

ans = 

    1 

Это также подразумевает ряд ограничений для строк в MATLAB. Что касается вашего вопроса, то вы не можете просто создать массив строк. Это будет точно конкатенация строк: если оба string1 и string2 являются просто целыми массивами, то [string1, string2] является конкатенацией двух строк.

Затем вы можете думать о укладке строк горизонтально, используя [string1; string2]. Теперь это работает точно так же, как и для двух целых массивов: вы можете сделать это только , если строки имеют равную длину (по длине теперь я имею в виду size(string1,2)).Поэтому в общем случае вы можете хранить строки только в неоднородном контейнере, т. Е. В MATLAB. После того, как у вас есть ячейки, ваши элементы могут иметь любой тип и форму, поэтому вы можете легко вставлять строки произвольной длины вместе, располагаться вертикально или горизонтально, но вам нравятся.

Так что рассмотрите textscan. Вам необходимо реализовать эту функцию, которая вернет данные, считанные из файла. Данные могут быть как числовыми, так и строковыми. Чем ты занимаешься? Именно то, что делает textscan: возвращает числовые столбцы как массивы (так как каждая строка имеет единичные скалярные данные) и возвращает строки как ячейки (поскольку каждая строка содержит строку, т. Е. Вектор сам по себе!). Вы можете стек строк горизонтально, но это работает только в том случае, если каждая строка в данном столбце содержит одинаковое количество символов, что, очевидно, не должно приниматься и не предписываться. Вы могли бы по-прежнему накладывать строки на самый длинный элемент и возвращать сложный массив символов, но это приведет к излишним накладным расходам в большинстве практических приложений. (Сторона примечания: textscan возвращает вектор строки ячейки в качестве своего вывода, причем каждый элемент ячейки содержит полные данные в данном столбце. Для числовых столбцов это «полные данные» - это вектор столбца массива, а для столбцов строки - столбец ячейки вектор.)

Так что разумно, что textscan возвращает свои столбцы строки как ячейки. Вы сами можете поместить свои строки в массив строк 2d, если хотите, но в большинстве случаев это не очень практично. Это действительно зависит от вашего приложения.

Минимальный пример: считать, что tmp.inp содержит

asf 3 4 
asdg 2 3 
asd 1 4 

Теперь

>> fid=fopen('tmp.inp','r'); outcell=textscan(fid,'%s%f%f'), fclose(fid); 

outcell = 

    {3x1 cell} [3x1 double] [3x1 double] 

Это демонстрирует тот факт, что выход outcell представляет собой вектор ячейки строки, каждый элемент, соответствующий колонке читать из файла. Квадратные скобки вокруг столбцов 2 и 3 показывают, что эти элементы ячейки (а именно outcell{2} и outcell{3}, которые не следует путать с outcell(2) и outcell(3)) представляют собой числовые массивы. Первый элемент, однако, является вектор-столбец ячейки:

>> outcell{1} 

ans = 

    'asf' 
    'asdg' 
    'asd' 

Тот факт, что вывод печатается в кавычках на каждой строке указывает на то, что это отдельные строки, содержащиеся в клетке, но вы можете также сказать, что это из

>> whos ans 
    Name  Size   Bytes Class Attributes 

    ans  3x1    356 cell    

Теперь, как я уже говорил, вы можете решить, чтобы сложить столбцы друг на друга, вам нужно только позвонить char() на свой мобильный:

>> char(outcell{1}) 

ans = 

asf 
asdg 
asd 

>> whos ans 
    Name  Size   Bytes Class Attributes 

    ans  3x4    24 char    

Обратите внимание на отсутствие кавычек в автоматическом выводе и класс/размер самого выхода. Размер 3x4 стал возможным, заполнив все строки до размера самой длинной строки, т. Е. 4. Следовательно, первая и третья строки вывода заканчиваются пробелом (это то, что мы понимаем под строками, получающими padded).

Если вы не выполняете эти отступы, вы можете просто ссылаться на ваши строки чтения в качестве клеточных элементов они:

>> outcell{1}{3} 

ans = 

asd 

Или, путь сохранения переменного, как вы хотели изначально:

>> compartment_name=outcell{1} 

compartment_name = 

    'asf' 
    'asdg' 
    'asd' 

>> compartment_name{3} 

ans = 

asd 
Смежные вопросы