Подтвердить что ты не робот

Matlab - индексирование массива с использованием строковых значений

У меня есть предопределенный массив из 20 позиций, которые соответствуют 20 суставам из моего тела. Соединения отмечены строковыми значениями (например, "left_knee", "head", "left_eye" и т.д.).

Я хочу ссылаться на определенное значение внутри массива, используя прикрепленное строковое значение. Например, я хочу сохранить положение наблюдаемых суставов. Первоначально все позиции в массиве (-1 , -1), а затем, если я обнаруживаю какой-то сустав, я хочу сделать что-то вроде Joints('left_knee') = [100 200].

Как я могу сделать это в Matlab?

4b9b3361

Ответ 1

Вы можете использовать встроенные контейнеры для карт для сопоставления значений уникальным клавишам. Вот вам быстрый пример:

valueSet = {[-1, 1], [2, 3], [1,5], [1,8]};
keySet = {'left_knee', 'right_knee', 'left_eye', 'right_eye'};
Joints = containers.Map(keySet,valueSet);
Joints('left_knee')

ans =
    -1     1

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

values(Joints)

ans = 
    [1x2 double]    [1x2 double]    [1x2 double]    [1x2 double]

keys(Joints)

ans = 
    'left_eye'    'left_knee'    'right_eye'    'right_knee'

Смотрите документацию для получения дополнительных "примеров и способов".

Ответ 2

Как насчет struct s?

Joints.left_knee = [100 200];
Joints.head      = [-1 -100];

Получить все поля с помощью fieldnames, динамически ссылаться на отдельные записи:

someVar = 'left_eye';
Joints.(someVar) = [200 250];

и т.д.. Если у вас есть несколько суставов, все из которых имеют одинаковые данные, но все они принадлежат к одной и той же системе, вы также можете создавать многомерные структуры:

Joints(1).left_knee = [100 200];
Joints(1).head      = [-1 -100];

Joints(2).left_knee = [200 450];
Joints(2).head      = [-10 -189];

Joints(3).left_knee = [-118 264];
Joints(3).head      = [+33  78];

Просто чтобы показать вам некоторые методы, полезные в контексте многомерных структур:

>> someVar = 'head';
>> Joints.(someVar)     % will be expanded cell-array, 1 entry for each dimension
ans =
    -1  -100
ans =
   -10  -189
ans =
    33    78
>> [Joints.(someVar)]   % will collect those data in regular array
ans =
    -1  -100   -10  -189    33    78
>> {Joints.(someVar)}   % will collect those data in cell array
ans = 
    [1x2 double]    [1x2 double]    [1x2 double]
>> [A,B,C] = deal(Joints.(someVar));  % will assign data to 3 separate vars
A =
    -1  -100
B =
   -10  -189
C =
    33    78

Введите help struct для получения дополнительной информации и ознакомьтесь с соответствующими функциями.

Ответ 3

Чтобы расширить решение @RodyOldenhuis, вы также можете хранить свои индексы в массиве struct и использовать простую матрицу для данных. Таким образом, вы все равно можете применить нормальную матричную операцию ко всем данным в векторном режиме:

idx.left_knee  = 1;
idx.right_knee = idx.left_knee + 1;
idx.left_elbow = idx.right_knee+ 1;
idx.right_elbow= idx.left_elbow+ 1;

joint_pos = rand(4,8);
t = linspace(0,1,8);
joint_vel = diff(joint_pos,2)./diff(t);

joint_vel(idx.right_knee,:)

В моем примере я создал структуру данных для позиции и скорости 4 суставов в 8 точках времени, чтобы проиллюстрировать мою технику.

С этим проще работать при использовании многомерных наборов данных. Конечно, это зависит от вашего приложения, если вы, например, просто хотите хранить константы, решение @RodyOldenhuis, очевидно, намного проще.