Matlab: как загрузить файл в виде массива структур - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь преобразовать файл данных (здесь строка, представляющая файл с тремя строками) в структурный массив, подобный следующему:

cel = textscan('1 1.1 2 2.2 3 3.3', '%u %f');
str = cell2struct(cel, {'f1', 'f2'}, 2);

Однако теперь у меня есть массив структур размером 1x1, где я могуполучить доступ только к столбцам, используя поля массива, но не целые строки (например, 'str (2)' для второй строки).

Мне нужно иметь массив структур (или как его можно назвать) вот так:

str = struct('f1', {1, 2, 3}, 'f2', {1.1, 2.2, 3.3});

потому что теперь я могу (например) отфильтровать это так:

subStr = str(find([str.f1] > 1))

, что я не смог сделать в первом случае.Есть идеи как туда добраться?В конце я смог сделать это следующим образом:

cel = textscan('1 1.1 2 2.2 3 3.3', '%u %f');
[f1, f2] = cel{:};
str = struct('f1', num2cell(f1'), 'f2', num2cell(f2'));

Но это не так, и я боюсь, что это будет дорого (файлы довольно большие).

РЕДАКТИРОВАТЬ:

Мое решение действительно слишком требовательно к памяти, поэтому его нельзя использовать.Типичные файлы имеют заголовок, нижний колонтитул и c.5e6 строк данных в шести столбцах.

Спасибо

Ответы [ 3 ]

0 голосов
/ 23 января 2019

Каждый элемент cel является массивом.С помощью cellfun и num2cell они могут быть преобразованы в массивы ячеек:

names = {'f1', 'f2'};
cel = textscan('1 1.1 2 2.2 3 3.3', '%u %f');
cel2 = cellfun(@num2cell, cel, 'UniformOutput', 0);

prep = [names;cel2];
str = struct(prep{:}).';
0 голосов
/ 24 января 2019

Хотелось бы, чтобы я читал их более внимательно раньше, но согласно , этому и этому не рекомендуется сохранять большие наборы данных так, как я пытался, потому что

Структуры с большим количеством полей и небольшим содержимым имеют большие накладные расходы, и их следует избегать.Большой массив структур с числовыми скалярными полями требует гораздо больше памяти, чем структура с полями, содержащими большие числовые массивы.

и

Для структур и массивов ячеек MATLAB создаетзаголовок не только для каждого массива, но также для каждого поля структуры и для каждой ячейки массива ячеек.Из-за этого объем памяти, необходимый для хранения структуры или массива ячеек, зависит не только от того, сколько данных они содержат, но и от того, как они построены.

Поэтому для массива str.f(1:N) требуется(для большего N) гораздо больше памяти, чем str(1:N).f.

0 голосов
/ 23 января 2019

Проще, если вы на самом деле работаете с файлом, содержащим строки. Например, если data.txt содержит:

1 1.1
2 2.2
3 3.3

А теперь вы можете просто загрузить это, используя:

tbl = readtable('data.txt');
tbl.Properties.VariableNames = {'f1', 'f2'};

Что приводит к гораздо более приятному (imho) синтаксису фильтрации:

subTbl = tbl(tbl.f1 > 1, :);

Я предлагаю вам прочитать немного о таблицах в MATLAB , чтобы узнать об их (многих) возможностях.


Наконец, если вы настаиваете на работе с struct массивами, вы можете сделать:

str = table2struct(tbl); 3×1 struct array with fields: f1 f2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...