2013-08-22 3 views
2

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

Я попытался с помощью простого

А (1, В) {2,2}

, но, конечно, это не работает .... Можете ли вы мне помочь?

+0

Поскольку вы сказали массив ячеек в массиве ячеек, не вы должны попробовать 'A {1, B} {2,2}' вместо этого, и если это Безразлично» t work 'tmp = A {1, B}; TMP {2,2} '? –

+0

@TobiasKienzler tmp = A {1, B} возвращает только ячейку, соответствующую первому элементу B. – gabboshow

+0

, если B [1 3 5] Я хотел бы иметь элемент {2,2} из A {1,1 }, A {1,3} и A {1,5} ... – gabboshow

ответ

2

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

+1

@ Dan Ah, правда, ваш ответ использует cellfun для получения элемента '{2,2}' каждой ячейки и обращается к элементам '(1, B)', мой наоборот. Интересно, какой из них лучше работает ... Но это, вероятно, зависит от размеров и субазмеров. –

+0

Если бы это был Python, ответ был бы более понятным: '[A [1] [b] [2] [2] для b в B] ' –

+0

Хорошо, если OP занимается эффективностью, его достаточно легко проверить.Но более вероятно, что он/она должен просто выбрать то, что кажется ему более интуитивным. Они очень похожи друг на друга – Dan

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 

EDIT:

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

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

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

cellfun(@(c)c{2,2}, A(1,B)) 
+1

Я думаю, что это ошибка в MATLAB, вам нужно использовать временную переменную в этом последнем утверждении: 'c = cellfun (@ (x) x (2,2), A); [c {1, B}] ' – Amro

+0

@Amro Я только что протестировал его, вы правы! Еще раз я был сорван испытанием в Октаве. – Dan

2

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

% 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, было бы лучше, если вы делаете эту операцию на петле, потому что они slow)

См. subsref документация here.

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

temp = [A{1,B}] 
temp{2,2} 
+1

Я получаю только элемент {2,2} первого элемента в 'B', используя оба ваших метода ... (т. Е. Запускать на моем примере' A' и 'B', который я разместил в своем решении, я получаю' ans = 8', не получаем '2') – Dan

+0

@ Дань Да, но если' B' большой, вы сделаете большую петлю, используя 'cellfun', который будет не очень быстрым. Subref является встроенной функцией matlab для вспомогательной ссылки на элемент ... – Werner

+0

@ Дань ах, позвольте мне проверить это – Werner

Смежные вопросы