Matlab - индексирование массива с использованием строковых значений
У меня есть предопределенный массив из 20 позиций, которые соответствуют 20 суставам из моего тела. Соединения отмечены строковыми значениями (например, "left_knee", "head", "left_eye" и т.д.).
Я хочу ссылаться на определенное значение внутри массива, используя прикрепленное строковое значение. Например, я хочу сохранить положение наблюдаемых суставов. Первоначально все позиции в массиве (-1 , -1)
, а затем, если я обнаруживаю какой-то сустав, я хочу сделать что-то вроде Joints('left_knee') = [100 200]
.
Как я могу сделать это в Matlab?
Ответы
Ответ 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, очевидно, намного проще.