Как мне манипулировать данными следующим образом? - PullRequest
0 голосов
/ 30 июня 2011

У меня есть файл с именем data.dat с содержимым (образец):

0.0 2.3 4.5 0.9 0.5 3.4 0.0 0.3 0.5 E F

2.9 5.4 7.2 4.8 3.7 9.1 2.3 4.1 5.6

3.4 6.1 4.8 6.4 0.4 0.6 0.3 5.4 7.1

0.0 2.3 4.5 0.9 0.5 3.4 0.0 0.3 0.5 E F

2.9 5.4 7.2 4.8 3.7 9.1 2.3 4.1 5.6

3.4 6.1 4.8 6.4 0.4 0.6 0.3 5.4 7.1

.
.
.

Я пытаюсь объединить каждый массив из 3 строк в один массив строк в конце, чтобы получить матрицу f x 29:

0.0 2.3 4.5 0.9 0.5 3.4 0.0 0.3 0.5 E F 2.9 5.4 7.2 4.8 3.7 9.1 2.3 4.1 5.6 3.4 6.1 4.8 6.4 0.4 0.6 0.3 5.4 7.1

0.0 2.3 4.5 0.9 0.5 3.4 0.0 0.3 0.5 E F 2.9 5.4 7.2 4.8 3.7 9.1 2.3 4.1 5.6 3.4 6.1 4.8 6.4 0.4 0.6 0.3 5.4 7.1

.
.
.

, а затем сместите 10-й и 11-й столбцы в 1-й и 2-й ряд:

E F 0.0 2.3 4.5 0.9 0.5 3.4 0.0 0.3 0.5 2.9 5.4 7.2 4.8 3.7 9.1 2.3 4.1 5.6 3.4 6.1 4.8 6.4 0.4 0.6 0.3 5.4 7.1

E F 0.0 2.3 4.5 0.9 0.5 3.4 0.0 0.3 0.5 2.9 5.4 7.2 4.8 3.7 9.1 2.3 4.1 5.6 3.4 6.1 4.8 6.4 0.4 0.6 0.3 5.4 7.1

Как мне это сделать в MATLAB? Вот моя попытка, но она неверна.

% Find out number of rows in file

rline=0;
x=0;

% Open Data File
fid = fopen('data.dat','rt');

% Loop through data file until we get a -1 indicating EOF
while(x~=(-1))
  x=fgetl(fid);
  rline=rline+1;
end
rline = rline-1;

% How many row in final file

fline=rline/3; % one row in final file represent by 3 rows from raw data

% Create 3 seperate matrix named as z1,z2,z3

frewind(fid);
for i = 1:rline
  num1 = fscanf(fid,'%f %f %f %f %f %f %f %f %f\n')'; % Read in numbers
  name1 = fscanf(fid,'%s %s',rline); % Filter out string at end of line
  if(i==1)
    result1 = num1; % Add 1st row
    names1 = name1; % Add 1st text string
  else
    result1 = [result1;num1]; % Add additional rows
    names1 = char(names1,name1); % Add next string
    names1 = names1';
  end
  i=i+3;
end

fclose(fid);

z1 = result1;
zname= names1;

frewind(fid);
for i = 2:rline
  num2 = fscanf(fid,'%f')'; % Read in numbers

  if(i==2)
    result2 = num2; % Add 2nd row
  else
    result2 = [result2;num2]; % Add additional rows    
  end
  i=i+3;
end

fclose(fid);

z2 = result2;

frewind(fid);
for i = 3:rline
  num3 = fscanf(fid,'%f')'; % Read in numbers    
  if(i==3)
    result3 = num3; % Add 3rd row    
  else
    result3 = [result3;num3]; % Add additional rows

  end
  i=i+3;
end

fclose(fid);

z3 = result3;

% Create a final data matrix of F = (fline x 29)

for i = 1: fline
    for j = 1: fline
        F(i, [1:2]) = zname(j,:);
        F(i, [3:11]) = z1(j,:);
        F(i, [12:20]) = z2(j,:);
        F(i, [21:29]) = z3(j,:);
        j=j+1;
    end
    i=i+1;
end

Final_data = [F];

Ответы [ 2 ]

0 голосов
/ 30 июня 2011

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

data.dat

0.0 2.3 4.5 0.9 0.5 3.4 0.0 0.3 0.5 E F
2.9 5.4 7.2 4.8 3.7 9.1 2.3 4.1 5.6
3.4 6.1 4.8 6.4 0.4 0.6 0.3 5.4 7.1
0.0 2.3 4.5 0.9 0.5 3.4 0.0 0.3 0.5 E F
2.9 5.4 7.2 4.8 3.7 9.1 2.3 4.1 5.6
3.4 6.1 4.8 6.4 0.4 0.6 0.3 5.4 7.1

код MATLAB

%# parse data file
fid = fopen('data.dat','rt');
C = textscan(fid, [repmat('%f ',[1 9]) '%s %s'], 'CollectOutput',true);
fclose(fid);

%# extract and reshape numeric data
M = C{1};
M = reshape(M', size(M,2)*3, [])';   %# similar to 'Michael J. Barber' answer

%# extract textual data
T = C{2}(1:3:end,:);

%# we can merge all into one cell array
data = [T num2cell(M)];

Обратите внимание, что поскольку данные содержат гетерогенные типы (числовые и символьные), мы читаем и храним их отдельно. Последняя строка кода показывает один способ объединения всех данных в один массив ячеек:

data = 
    'E'    'F'    [0]    [2.3000]    [4.5000]    [0.9000]    [0.5000]    [3.4000]    [0]    [0.3000]    [0.5000]    [2.9000]    [5.4000]    [7.2000]    [4.8000]    [3.7000]    [9.1000]    [2.3000]    [4.1000]    [5.6000]    [3.4000]    [6.1000]    [4.8000]    [6.4000]    [0.4000]    [0.6000]    [0.3000]    [5.4000]    [7.1000]
    'E'    'F'    [0]    [2.3000]    [4.5000]    [0.9000]    [0.5000]    [3.4000]    [0]    [0.3000]    [0.5000]    [2.9000]    [5.4000]    [7.2000]    [4.8000]    [3.7000]    [9.1000]    [2.3000]    [4.1000]    [5.6000]    [3.4000]    [6.1000]    [4.8000]    [6.4000]    [0.4000]    [0.6000]    [0.3000]    [5.4000]    [7.1000]
0 голосов
/ 30 июня 2011

Вы можете довольно легко манипулировать массивами, используя Matlab, циклы не нужны.Я буду использовать меньший массив, чтобы было легче увидеть, что происходит.Я также буду использовать Octave, но здесь нет никакой разницы.Я также предполагаю, что матрица уже доступна в переменной (для этого используйте load, это намного проще, чем подход в вопросе).

Сначала рассмотрим матрицу A:

octave-3.0.0:23> A
A =

    1    7
    2    8
    3    9
    4   10
    5   11
    6   12

Объединение первых трех строк можно выполнить с помощью reshape.Поскольку Matlab работает по столбцам, вам действительно нужно применить reshape к транспонированию A:

octave-3.0.0:24> B = reshape(A', 6, 2)'
B =

    1    7    2    8    3    9
    4   10    5   11    6   12

Чтобы изменить положение столбцов, просто используйте прекрасные возможности Matlab по индексированию.Укажите вектор с нужным порядком в качестве индекса столбца, взяв все строки, указав двоеточие : в качестве индекса строки:

octave-3.0.0:25> B(:,[5,6,1:4])
ans =

    3    9    1    7    2    8
    6   12    4   10    5   11
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...