Доступ к предопределенным элементам ячеек

У меня есть массив ячеек A [1x80], в котором каждый элемент является самим массивом ячеек [9x2]. У меня также есть вектор B, представляющий группу выбранных ячеек A, и я хочу извлечь элемент {2,2} каждой выбранной ячейки.

Я пробовал с помощью простого

A(1,B){2,2}

но, конечно, это не работает.... Вы можете мне помочь?


person gabboshow    schedule 22.08.2013    source источник
comment
Поскольку вы сказали массив ячеек в массиве ячеек, не следует ли вам вместо этого попробовать A{1,B}{2,2}, а если это не сработает, tmp = A{1,B}; tmp{2,2}?   -  person Tobias Kienzler    schedule 22.08.2013
comment
@TobiasKienzler tmp = A{1,B} возвращает только ячейку, соответствующую первому элементу B.   -  person gabboshow    schedule 22.08.2013
comment
если B равно [1 3 5], я хотел бы иметь элемент {2,2} из A{1,1}, A{1,3} и A{1,5}...   -  person gabboshow    schedule 22.08.2013
comment
Я думаю, ваша проблема заключается в доступе к верхней ячейке как (), где должно быть {}. Если вы используете (), он возвращает саму ячейку, а не элементы внутри ячейки.   -  person Werner    schedule 22.08.2013


Ответы (3)


Как насчет этого:

A = {{1 2; 3 4}, {5 6;7 8}, {9 0; 1 2}; {3 4; 5 6}, {7 8; 9 0}, {11 22; 33 44}};
B = [2,3]

[cellfun(@(x)x(2,2), A){1, B}]

ans =

   8   2

ИЗМЕНИТЬ:

Вышеупомянутое на самом деле работает только в октаве. Как указывает @Amro, чтобы изменить его для работы в Matlab, вам нужно использовать временную переменную:

temp = cellfun(@(x)x(2,2), A);
[temp{1, B}]

или в один лайнер (также благодаря @Amro)

cellfun(@(c)c{2,2}, A(1,B))
person Dan    schedule 22.08.2013
comment
Я думаю, что это приведет к ошибке в MATLAB, вам нужно использовать временную переменную в этом последнем выражении: c = cellfun(@(x)x(2,2), A); [c{1,B}] - person Amro; 23.08.2013
comment
@ Амро, я только что проверил, ты прав! В очередной раз мне помешало тестирование в Octave. - person Dan; 23.08.2013

Этот ответ такой же, как у @Dan, но при необходимости используется простой цикл for для повышения производительности.

% If you know that the numel of elements returned by {2,2} will always be one:
nElem = numel(B);
ret(1,nElem)=0;

for k=1:nElem

  ret(k) = A{1,B(k)}{2,2}

end

Следующий ответ неверен, он вернет только индекс {2,2} из первого элемента из B

subsref([A{1,B}],struct('type','{}','subs',{{2,2}}))

Это больше похоже на то, что вы делаете (и не использует cellfun и arrayfun, было бы лучше, если бы вы выполняли эту операцию в цикле, потому что они медленно)

См. subsref документацию здесь.

Более длинный путь будет:

temp = [A{1,B}]
temp{2,2}
person Werner    schedule 22.08.2013
comment
Я получаю только элемент {2,2} первого элемента в B, используя оба ваших метода... (т.е. запустив мои образцы A и B, которые я разместил в своем решении, я получаю ans = 8, не получайте 2) - person Dan; 22.08.2013
comment
@Dan Да, но если B большое, вы сделаете большой цикл, используя cellfun, что будет не очень быстро. Subsref — это встроенная функция Matlab для подссылки на элемент… - person Werner; 22.08.2013
comment
@ Дэн, окей, дай мне проверить - person Werner; 22.08.2013
comment
@Dan Да, вы правы, может быть способ исправить subsref для доступа к каждому элементу, но я думаю, что ему нужен цикл, если ему нужна производительность, он может сделать цикл for для доступа, в противном случае он может использовать cellfun для удобство как в вашем ответе х) - person Werner; 22.08.2013

Как насчет arrayfun(@(x) A{1,x}{2,2}, B)
или (спасибо @Amro) cellfun(@(c)c{2,2}, A(1,B))?

person Tobias Kienzler    schedule 22.08.2013
comment
@Dan Да, правда, в вашем ответе используется cellfun для получения элемента {2,2} каждой ячейки и доступа к элементам (1,B), а наоборот. Интересно, какой из них работает лучше... Но это, вероятно, зависит от размеров и подразмеров. - person Tobias Kienzler; 22.08.2013
comment
Если бы это был Python, ответ был бы более понятным: [A[1][b][2][2] for b in B] - person Tobias Kienzler; 22.08.2013
comment
Что ж, если ОП касается эффективности, его достаточно легко проверить. Но, скорее всего, ему следует просто выбрать то, что кажется ему более интуитивным. В остальном они очень похожи - person Dan; 22.08.2013
comment
@TobiasKienzler: аналогично: cellfun(@(c)c{2,2}, A(1,B)) - person Amro; 23.08.2013
comment
@Amro Я бы тоже так сказал, но OP указывает A(1,B) (разве не должно быть A{1,B}?) вернет только A(1,B(1)). У меня больше нет MATLAB, поэтому я не могу это проверить. - person Tobias Kienzler; 23.08.2013
comment
А, я вижу Дэн уже это проверил, так что Я отредактирую его. Но, вероятно, проблема temp-var также применима к моему arrayfun-решению, или это работает напрямую? - person Tobias Kienzler; 23.08.2013
comment
@TobiasKienzler: временные переменные не нужны, оба решения работают в MATLAB и Octave. кстати, если вам нужен быстрый доступ к Octave (который в большинстве случаев такой же, как MATLAB), попробуйте ideone.com - person Amro; 23.08.2013