MATLAB: прокрутите значения списка из функции «кто»

У меня есть длинный список переменных в моей рабочей области. Во-первых, я нахожу потенциальные переменные, которые могут меня заинтересовать, используя функцию who. Затем я хотел бы просмотреть этот список, чтобы найти размер каждой переменной, однако who выводит только имена переменных в виде строки.

Как я могу использовать этот список для ссылки на значения переменных, а не только на имя?

Спасибо,

list = who('*time*')
list = 

    'time'
    'time_1'
    'time_2'

for i = 1:size(list,1);
    len(i,1) = length(list(i))
end

len =

     1
     1
     1

person Bensa    schedule 24.10.2016    source источник
comment
Именно по этой причине имена динамических переменных плохи. Вы связываете себе руку и ведете себя по каменистой тропе, которая заканчивается в eval. Я предлагаю вам вместо этого использовать ячейку или, что еще лучше, структуру для хранения ваших данных. Таким образом, вместо time, time_1, time_2 и т. д. используйте timestruc.f1, timestruc.f2 и т. д. Вы можете получить доступ к этим полям динамически, используя timestruc.('f1').   -  person Andras Deak    schedule 24.10.2016


Ответы (3)


Если вам нужны подробности о переменных, вы можете вместо этого использовать whos, который вернет структуру, содержащую (среди прочего) измерения (size) и размер хранилища (bytes).

Что касается получения значения, вы можете использовать eval но это не рекомендуется, и вместо этого вам следует рассмотреть возможность использования массивов ячеек или структур с динамическими именами полей, а не динамическими имена переменных.

S = whos('*time*');

for k = 1:numel(S)
    disp(S(k).name)
    disp(S(k).bytes)
    disp(S(k).size)

    % The number of elements
    len(k) = prod(S(k).size);

    % You CAN get the value this way (not recommended)
    value = eval(S(k).name);
end
person Suever    schedule 24.10.2016
comment
спасибо за помощь. Как я могу использовать список whos в цикле for для назначения полей struct, которые также будут содержать значения time, а не только имя, байты и размер? - person Bensa; 25.10.2016
comment
Это другой вопрос, чем то, что вы задали здесь. Я предлагаю задать новый вопрос и отметить его как решение, если он ответил на ваш первоначальный вопрос. - person Suever; 25.10.2016

@Suever прекрасно объяснил простой способ получить эту информацию. Как я отметил в комментарии, я предлагаю вам сделать шаг назад и не создавать эти переменные с динамическими именами для начала.

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

timestruc.field = time;
timestruc.('field1') = time_1;
fname = 'field2';
timestruc.(fname) = time_2;

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

Но вот быстрый выход из ловушки, в которую вы попали: сохраните свое рабочее пространство (ну, соответствующую часть) в файле .mat и прочитайте его обратно. Вы можете сделать это таким образом, что вы получите структуру с поля, которые являются именно вашими именами переменных:

time = 1;
time_1 = 2;
time_2 = rand(4);
save('tmp.mat','time*'); % or just save('tmp.mat')
S = load('tmp.mat');

после этого S будет структурой, каждое поле будет соответствовать переменной, которую вы сохранили в 'tmp.mat':

>> S

S = 

      time: 1
    time_1: 2
    time_2: [4x4 double]
person Andras Deak    schedule 24.10.2016
comment
@ Андрас, спасибо за помощь. Есть ли способ назначить struct, используя список, найденный из whos, вместо того, чтобы вручную назначать каждый field? Таким образом, для каждого набора данных имена переменных могут быть разными, а также частота дискретизации. Для приведенного выше примера я хотел бы сгруппировать эти переменные time и выяснить, какие другие переменные соответствуют размеру каждого из этих времен, или, другими словами, сгруппировать каналы с соответствующими time на основе длины переменных. - person Bensa; 25.10.2016
comment
@BehnazEnsan Я не уверен, что понимаю ваш вопрос. Если вы хотите преобразовать свои переменные с именами time_1, time_2 и т. д. в поля новой структуры, это можно сделать только с помощью eval (от чего я бы не советовал) или с помощью save/load, как я объяснил в своем ответе. Затем, если у вас есть ячейка с именами полей в виде строк, tcell = {'time_1','time_2'}; и т. д., вы можете перебрать эту ячейку и динамически получить доступ к данному полю структуры: for tstring in tcell, tmpvar = S.(tstring); <do stuff here>; end. Или вы можете просто перебрать поля структуры fieldnames(S) и использовать это. - person Andras Deak; 25.10.2016

Пример записи переменных из рабочей области в файлы csv:

clear;

% Writing variables of myfile.mat to csv files
load('myfile.mat');
allvars = who;
for i=1:length(allvars)
    varname = strjoin(allvars(i));
    evalstr = strcat('csvwrite(', char(39), varname, '.csv', char(39), ', ', varname, ')');
    eval(evalstr);
end
person JPeti    schedule 16.08.2018