Предположим, что C
- это массив ячеек с формой M & times; 1 (т.е. size(C)
возвращает [M 1]) и что каждый элемент C
, в свою очередь, является массивом ячеек с форма 1 & times; N.
Я часто хочу преобразовать такой массив ячеек в новый массив ячеек D
, имеющий форму 1 & times; N, причем элементами являются массивы ячеек с формой M & times; 1 и такие, что C{i}{j}
equals D{j}{i}
для всех 0 < я & leq; M и 0 < & le; N.
Я использую следующую чудовищность для этого
D = arrayfun(@(j) arrayfun(@(i) C{i}{j}, (1:M)', 'un', 0), 1:N, 'un', 0);
но потребность в этой операции возникает достаточно часто (в конце концов, это своего рода "транспонирование ячеек массива" ), о которой я думал, я бы спросил:
существует ли более стандартный способ выполнения этой операции?
Обратите внимание, что желаемый D
отличается от
E = cat(2, C{:});
или, что эквивалентно,
E = cat(1, D{:});
Примером E
является двумерный (M & times; N) массив ячеек, тогда как оба C
и D
являются одномерными клеточными массивами одномерных ячеек. Конечно, преобразование E
обратно в C
или D
также является еще одной часто требуемой операцией (такого рода вещи никогда не заканчиваются с MATLAB), но я оставлю это для другого сообщения.
Мотивация этого вопроса выходит далеко за рамки проблемы, описанной выше. Оказывается, огромная часть моего кода MATLAB и еще большая часть моего времени и усилий по программированию MATLAB посвящена этой, по существу, непроизводительной работе по преобразованию данных из одного формата в другой. Конечно, преобразование формата неизбежно при выполнении какой-либо вычислительной работы, но с MATLAB я считаю, что делаю это намного больше или, по крайней мере, должен работать с ним намного сложнее, чем когда я работаю в других системах (например, Mathematica или Python/NumPy). Я надеюсь, что, создав свой репертуар MATLAB "трюки для преобразования формата", я смогу довести до более разумного уровня долю моего времени программирования MATLAB, которое я должен посвятить преобразованию формата. Суб >
P.S. Следующий код строит a C
, подобный описанному выше, для M = 5 и N = 2.
uc = ['A':'Z'];
randstr = @() uc(randi(26, [1 4]));
M = 5;
rng(0); % keep example reproducible
C = arrayfun(@(i) {randstr() i}, 1:M, 'un', 0)';
% C =
% {1x2 cell}
% {1x2 cell}
% {1x2 cell}
% {1x2 cell}
% {1x2 cell}
% >> cat(1, C{:});
% ans =
% 'VXDX' [1]
% 'QCHO' [2]
% 'YZEZ' [3]
% 'YMUD' [4]
% 'KXUY' [5]
%
N = 2;
D = arrayfun(@(j) arrayfun(@(i) C{i}{j}, (1:M)', 'un', 0), 1:N, 'un', 0);
% D =
% {5x1 cell} {5x1 cell}