首页 文章

在Matlab中是否有相当于Python的列表和追加功能?

提问于
浏览
3

这是一个Matlab编程问题而不是数学问题 .

我想在不同的学习率下运行梯度下降倍数 . 我有一套学习率

alpha = [0.3, 0.1, 0.03, 0.01, 0.003, 0.001];

每次我运行梯度下降时,我得到一个矢量 J_vals 作为输出 . 但是,我不熟悉Matlab,除了做类似的事情之外,还知道如何实现这个:

[theta, J_vals] = gradientDescent(...., alpha(1),...);
J1 = J_vals;
[theta, J_vals] = gradientDescent(...., alpha(2),...);
J2 = J_vals;

等等 .

我想过使用for循环,但后来我不知道如何处理 J_vals (不知道如何将for循环应用到 J1J2 等) . 也许它看起来像这样:

for i = len(alpha)
     [theta, J_vals] = gradientDescent(..., alpha(i),...);
     J(i) = J_vals;
end

然后我会有一个矢量矢量 .

在Python中,我只是运行for循环并将每个新结果附加到列表的末尾 . 我如何在Matlab中实现这样的东西?还是有更有效的方法?

3 回答

  • 1

    如果你知道你将要有多少循环和 J_vals 的大小(或至少是一个合理的上限)我建议预先分配容器数组的大小

    J = zeros(n,1);
    

    然后在每个循环上插入新值

    J(start:start+n) = J_vals
    

    这样你就不会重新分配内存 . 如果您不知道,可以将值附加到数组中 . 例如,

    J = []; % initialize
    for i = len(alpha)
         [theta, J_vals] = gradientDescent(..., alpha(i),...);
        J = [J; J_vals]; % Append column row
    end
    

    但这是每个循环重新分配数组的大小 . 如果它不是太多循环那么它应该没问题 .

  • 2

    只要为行下标添加 : (假设 J_vals 是列向量),您的解决方案就可以正常工作:

    for i = len(alpha)
         [theta, J_vals] = gradientDescent(..., alpha(i),...);
         J(:, i) = J_vals;
      %//  ^... all rows, column 'i'
    end
    

    您甚至可以将其作为返回值:

    for i = len(alpha)
         [theta, J(:, i)] = gradientDescent(..., alpha(i),...);
         %//       ^... add returned value directly to our list
    end
    

    这两种方法都允许您预先分配矩阵以获得潜在的速度增益 .

    如果你想要随时 Build 你的列表,你可以使用@ dpmcmlxxvi的答案中的方法,或者你可以使用特殊的下标 end . 但是,这些方法都不与预分配兼容 .

    for i = len(alpha)
         [theta, J(:, end+1)] = gradientDescent(..., alpha(i),...);
         %//          ^... add new vector after the current end of list
    end
    

    我还建议你不要在Matlab中使用 i 作为变量名 . 我知道这对其他语言来说很自然,但在Matlab中它会覆盖内置的虚数常量 i .
    见:https://stackoverflow.com/a/14790765/1377097

  • 3

    Matlab的"cell arrays"有点像Python中的列表 . 它们之间的相似之处在于您可以将变量数据类型放入其中 . 似乎没有人太确定,但most likely the cell array is implemented as an array of object pointers.这意味着追加它仍然有点昂贵( cell_array{length(cell_array) + 1} = new_data ),但至少你只是附加一个指针而不是整个列 . 您仍然需要使用cell2mat将单元格数组转换为普通矩阵 .

    最惯用的Matlab解决方案是预分配(如建议的@dpmcmlxxvi) .

    我认为你所描述的是一个非常常见的用例,不幸的是Matlab需要这样一个冗长的习惯用法 . 同样令人沮丧的是,文档对于如何实现单元阵列是不透明的,以及附加到单元阵列是否昂贵 .

相关问题