Чтение данных из текстового файла в массив Matlab

У меня возникают трудности с чтением данных из файла .txt с помощью Matlab.

Мне нужно создать массив размеров 200x128 в Matlab, используя данные из файла .txt. Это повторяющаяся задача, и она нуждается в автоматизации.

Каждая строка файла .txt представляет собой комплексное число в форме a+ib, которое имеет форму a[пробел]b. Пример моего текстового файла:

Ссылка на текстовый файл: Нажмите здесь

(0)

1.2 2.32222

2.12 3.113

.

.

.

3.2 2.22

(1)

4.4 3.4444

2.33 2.11

2.3 33.3

.

.

.

(2)

.

.

(3)

.

.

(199)

.

.

У меня есть номера строк (X) внутри файла .txt, заключенные в скобки. Моя окончательная матрица должна иметь размер 200x128. После каждого (X) идет ровно 128 комплексных чисел.


person sudhishkr    schedule 09.06.2014    source источник


Ответы (2)


Вот что я бы сделал. Прежде всего, удалите строки типа «(0)» из вашего текстового файла (для этого можно даже использовать простой сценарий оболочки). Это я поместил в файл с именем post2.txt.

# First, load the text file into Matlab:
A = load('post2.txt');

# Create the imaginary numbers based on the two columns of data:
vals = A(:,1) + i*A(:,2);

# Then reshape the column of complex numbers into a matrix
mat = reshape(vals, [200,128]);

mat будет матрицей комплексных данных 200x128. Очевидно, что в этот момент вы можете зациклить это, чтобы сделать это несколько раз.

Надеюсь, это поможет.

person brechmos    schedule 09.06.2014
comment
Я не очень хорошо разбираюсь в сценариях оболочки, в итоге я написал 25-строчный код на Python для создания post2. Если бы вы могли поделиться, как это сделать в оболочке, это будет полезно в будущем. Спасибо еще раз! Кроме того, ваш код должен был быть изменен (vals, [128,200])' . - person sudhishkr; 09.06.2014
comment
@Suddev: Если вы работаете в системе на основе Unix, вы можете просто использовать инвертированный grep, такой как: grep -v '^(' post.txt › post2.txt Это выводит все строки, которые не начинаются со скобки. - person brechmos; 09.06.2014
comment
я был на Windows, я попробовал то, что вы сказали, на машине на базе Unix. Работает - еще раз спасибо! - person sudhishkr; 11.06.2014

Вы можете прочитать данные, используя следующую функцию:

function data = readData(aFilename, m,n)

% if no parameters were passed, use these as defaults:
if ~exist('aFilename', 'var')
    m = 128;
    n = 200;
    aFilename = 'post.txt';
end

% init some stuff:
data= nan(n, m);
formatStr = [repmat('%f', 1, 2*m)];

% Read in the Data:
fid = fopen(aFilename);
for ind = 1:n
    lineID = fgetl(fid);
    dataLine = fscanf(fid, formatStr);
    dataLineComplex = dataLine(1:2:end) + dataLine(2:2:end)*1i;
    data(ind, :) = dataLineComplex;
end
fclose(fid);

(редактировать) Эту функцию можно улучшить, включив части (1) в строку формата и исключив их:

function data = readData(aFilename, m,n)

% if no parameters were passed, use these as defaults:
if ~exist('aFilename', 'var')
    m = 128;
    n = 200;
    aFilename = 'post.txt';
end

% init format stuff:
formatStr = ['(%*d)\n' repmat('%f%f\n', 1, m)];

% Read in the Data:
fid = fopen(aFilename);

data = fscanf(fid, formatStr);
data = data(1:2:end) + data(2:2:end)*1i;
data = reshape(data, n,m);

fclose(fid);
person Steve    schedule 09.06.2014
comment
Я собираюсь объединить ваш ответ и ответ @brechmos, чтобы решить эту проблему. Я надеюсь, что смогу сделать это в ближайшее время. - person sudhishkr; 09.06.2014
comment
@ Стив, зачем использовать нан (n, m). Может быть, лучше сделать нули (n, m). Это более привычно, но, возможно, я что-то упускаю. (Зависит от предположений, я полагаю). Я подозреваю, что такой цикл будет менее эффективным, чем использование внутренней функции загрузки. - person brechmos; 09.06.2014
comment
@Suddev: Если вы работаете в системе на основе Unix, вы можете просто использовать инвертированный grep, такой как: grep -v '^(' post.txt › post2.txt Это выводит все строки, которые не подходят начни со скобки. - person brechmos; 09.06.2014
comment
@brechmos Что касается команды load, неясно, какая из них быстрее, хотя вы вполне можете быть правы. MATLAB load построен для гибкости, в то время как цикл работает медленно для больших значений. Я хотел использовать строку формата formatStr = ['(%*d)' repmat('%f', 1, 2*m)];, а затем загрузить весь файл сразу — вероятно, довольно быстро, но он завис после записи первой строки, поэтому я зациклил его. В любом случае, поскольку файлы маленькие, штраф за это небольшой. Чтобы заставить этот конкретный формат работать, это казалось достаточно быстрым решением. - person Steve; 09.06.2014
comment
@brechmos Что касается значений nan, мне часто нравится делать это, чтобы, если в коде есть ошибка индексации, эти значения nan представляли собой неприятный индикатор для будущей обработки. Кроме того, я исправил строку формата, добавив \n, и добавил к ответу пример без цикла. Для вас ‹3 - person Steve; 09.06.2014
comment
@Steve: Понятно, это имеет смысл в отношении значений nan. Очевидно, зависит от предположений. Для того, что я делаю (обработка изображений), 0 — отличное значение по умолчанию. Мне нравится без петель. :-) - person brechmos; 09.06.2014