У меня есть массив ячеек [5x1], все ячейки которого являются векторами-столбцами, например:

exInt =

    [46x1 double]
    [54x1 double]
    [40x1 double]
    [51x1 double]
    [ 9x1 double]

Мне нужен вектор (vec), содержащий ячейки в extInt, которые мне нужно извлечь, а затем мне нужно преобразовать их в массив с одним столбцом. Такие как:

    vec = [1,3];
    Output = cell2mat(extInt{vec})

На выходе должен получиться массив [86x1 double].

То, как я закодировал, я получаю:

Error using cell2mat
Too many input arguments.

Если возможно, я хотел бы иметь решение, не использующее цикл.

0
Artur Castiel 6 Сен 2016 в 15:05

3 ответа

Лучший ответ

Лучшим подходом здесь является использование cat вместе с разделенный запятыми список, созданный {{X1 }} индексация для получения ожидаемого вектора столбца. Мы указываем первое измерение в качестве первого аргумента, поскольку у вас есть все векторы-столбцы, и мы хотим, чтобы выходные данные также были вектором-столбцом.

out = cat(1, extInt{vec})

Учитывая введенные вами данные, cell2mat пытается объединить по второму измерению , что не удастся для ваших данных, поскольку все данные имеют разное количество строк. Вот почему (в вашем примере) вам пришлось перенести данные перед вызовом cell2mat.

Обновить

Вот эталон для сравнения времени выполнения подходов cat и cell2mat.

function benchit()

    nRows = linspace(10, 1000, 100);

    [times1, times2] = deal(zeros(size(nRows)));

    for k = 1:numel(nRows)

        rows = nRows(k);

        data = arrayfun(@(x)rand(randi([10, 50], 1), 1), 1:rows, 'uni', 0);
        vec = 1:2:numel(data);

        times1(k) = timeit(@()cat_method(data, vec));

        data = arrayfun(@(x)rand(randi([10, 50], 1), 1), 1:rows, 'uni', 0);
        vec = 1:2:numel(data);

        times2(k) = timeit(@()cell2mat_method(data, vec));
    end

    figure

    hplot(1) = plot(nRows, times1 * 1000, 'DisplayName', 'cat');
    hold on
    hplot(2) = plot(nRows, times2 * 1000, 'DisplayName', 'cell2mat');

    ylabel('Execution Times (ms)')
    xlabel('# of Cell Array Elements')

    legend(hplot)
end

function out = cat_method(data, vec)
    out = cat(1, data{vec});
end

function out = cell2mat_method(data, vec)
    out = cell2mat(data(vec)');
end

enter image description here

Причина постоянного смещения между ними в том, что cell2mat вызывает cat внутри, но добавляет к нему некоторую дополнительную логику. Если вы просто используете cat напрямую, вы обойдете эти дополнительные накладные расходы.

4
Suever 6 Сен 2016 в 15:10

Использовать

 Output = cell2mat(extInt(vec))

Поскольку вы хотите адресовать ячейки в extInt, а не содержимое ячеек

extInt(vec)
extInt{vec}

Попробуйте их, чтобы увидеть, что происходит

0
ben 6 Сен 2016 в 12:24

Я бездельничал, и у меня это получилось, преобразовав эту запись в новый массив ячеек и переставив его, чтобы размеры оставались эквивалентными для процесса конкатенации

Output = cell2mat({extInt{vec}}')
0
Artur Castiel 6 Сен 2016 в 12:22