2014-06-10 3 views
1

У меня есть код, который создает выходные файлы, содержащие информацию о некоторой сетке, которую мне нужно проанализировать с помощью MATLAB.Извлечь только числовые данные из MATLAB из текстового файла в матрицу

Выходные файлы выглядят следующим образом.

Vertex 1 1.3 -2.1 0 {z=(1.3e+0 -2.1e+0) mu=(1.4e-3 2.0e-3) uv=(-0.6 0.4)} 
Vertex 2 1.4 -2.1 0 {z=(1.4e+0 -2.1e+0) mu=(2.8e-3 1.5e-3) uv=(-0.6 0.4)} 
Vertex 3 -1.9 1.9 0 {z=(-1.9e+0 1.9e+0) mu=(-8.9e-2 1.4e-1) uv=(0.7 -0.2)} 
. 
. 
. 

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

Так например я хотел бы вышеупомянутые 3 линии, которые будут обработаны в матрицу

1 1.3 -2.1 0 1.3e+0 -2.1e+0 1.4e-3 2.0e-3 -0.6 0.4 
2 1.4 -2.1 0 1.4e+0 -2.1e+0 2.8e-3 1.5e-3 -0.6 0.4 
3 -1.9 1.9 0 -1.9e+0 1.9e+0 -8.9e-2 1.4e-1 0.7 -0.2 

Есть ли какие-либо удобные MATLAB объект/команда, чтобы сделать это?

ответ

1

Я думаю, вы могли бы использовать для этого textscan:

Пример date.txt:

Vertex 1 1.3 -2.1 0 {z=(1.3e+0 -2.1e+0) mu=(1.4e-3 2.0e-3) uv=(-0.6 0.4)} 
Vertex 2 1.4 -2.1 0 {z=(1.4e+0 -2.1e+0) mu=(2.8e-3 1.5e-3) uv=(-0.6 0.4)} 
Vertex 3 -1.9 1.9 0 {z=(-1.9e+0 1.9e+0) mu=(-8.9e-2 1.4e-1) uv=(0.7 -0.2)} 

Код:

fileID = fopen('data.txt'); 

C = textscan(fileID,'Vertex %f %f %f %f {z=(%f %f) mu=(%f %f) uv=(%f %f)}'); 

fclose(fileID); 

mtxC = [C{:}]; 

Результат:

mtxC = 

    1.0000 1.3000 -2.1000   0 1.3000 -2.1000 0.0014 0.0020 -0.6000 0.4000 
    2.0000 1.4000 -2.1000   0 1.4000 -2.1000 0.0028 0.0015 -0.6000 0.4000 
    3.0000 -1.9000 1.9000   0 -1.9000 1.9000 -0.0890 0.1400 0.7000 -0.2000 
0

MATLAB Option (частично проверенный)

я должен был сделать что-то подобное с КИМ один раз, и это было легко сделать в Python (см. Ниже) Вы можете использовать команду MATLAB regexp(text, expression), чтобы соответствовать регулярному выражению, которое получает то, что вы хотите. Это приведет к возврату строковых данных, хотя вы можете сохранить их в файле данных, а затем load that data file или преобразовать в номера с помощью str2double.

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

in_fid = fopen('my_input_file.txt', 'r'); 
out_fid = fopen('my_output_file.txt', 'w'); 
data = []; 

line = fgetl(in_fid); 
while ischar(line) 
    match = regexp(line, '[+-]?\d+\.?\d*e?[+-]?\d*', 'match'); % find all matches 

    % Write to text file 
    fprintf(out_fid, '%s\t', match); % write values to file with tabs between 
    fprintf(out_fid, '\n'); % write a new line to the file 

    % Or save to an array locally 
    data = [data; str2double(match)]; 

    line = fgetl(in_fid); % grab the next line 
end 
fclose('all'); 

% If you wrote to a text file, retrieve the data 
data = dlmread('my_output_file.txt', 'delimiter', '\t'); % not sure about this... 

Обратите внимание, что это будет не число матчей, которые начинаются с десятичной точкой, без предшествующего знака, т.е. .2. Также обратите внимание, что это будет соответствовать номерам, которые соответствуют шаблону в любом файле, который вы его кормите, поэтому он обобщен. Для того, чтобы совместить числа с плавающей запятой, see this site (я немного изменил это, добавив часть e для научной нотации).

Я смог проверить операции regexp и str2double на удаленной машине, и похоже, что ваш массив данных напрямую работает. Я не смог проверить часть ввода-вывода файла, так что там могут быть некоторые ошибки.

Python Option (мой любимый)

Я предлагаю использовать регулярные выражения в Python для такого рода вещи. Я должен был сделать что-то подобное с КИМ один раз, и это было легко сделать в Python с чем-то вроде:

import re 

# Make pattern to match scientific notation numbers 
pattern = re.compile(r"[+-]?\d+\.?\d*e?[+-]?\d*") 

with open("your_input_file.txt", "r") as in_file: 
    with open("your_output_file.txt", "w") as out_file: 
     for line in in_file: 
      match = pattern.findall(line) # find all matches in the line 
      out_file.write("\t".join(match) + "\n") # write the results to a line in your output 

Для хорошего введения в регулярное выражение в Python см Dive Into Python 3, который я рекомендую только о все читает. Я проверил это на примере файл, и это дает мне:

1 1.3 -2.1 0 1.3e+0 -2.1e+0 1.4e-3 2.0e-3 -0.6 0.4 
2 1.4 -2.1 0 1.4e+0 -2.1e+0 2.8e-3 1.5e-3 -0.6 0.4 
3 -1.9 1.9 0 -1.9e+0 1.9e+0 -8.9e-2 1.4e-1 0.7 -0.2 

в your_output_file.txt, так что я думаю, что это работает! Последним шагом будет только dlmread('your_output_file.txt', 'delimeter', '\t') в MATLAB, и вам должно быть хорошо идти.

Если вы хотите получить фантазию, вы можете обновить свой скрипт Python, чтобы его можно было вызвать из командной строки с вашими входными и выходными файлами в качестве аргументов (посмотрите на метод), но это становится немного сложнее и достаточно просто открыть скрипт и вручную изменить имя файла. Если вам не нужно делать это все время в файлах с разными именами, и в этом случае аргументы - хороший маршрут.There is a good example of this here.

+1

Обычно я бы вниз голосуйте, так как ответ в основном о python и OP не спрашивают о python. В противном случае, почему бы не дать ответ в JavaScript или PHP или Ruby или perl. Пожалуйста, не делай этого. – Marcin

+0

Python, потому что у меня была именно эта проблема, и Python был проще реализовать, чем MATLAB. Если кто-то предлагает лучший ответ, который использует MATLAB исключительно тогда, это будет мой голос за «правильный ответ», но это делает именно то, что хочет OP, и, imo, проще реализовать. – Engineero

+0

Но вопрос о Matlab: «Есть ли какая-то удобная установка/команда MATLAB для этого?» – Marcin

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