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

时间:2015-08-20 01:23:04

标签: python arrays matlab

这更像是一个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循环应用于J1,{{1 }}, 等等)。也许它看起来像这样:

J2

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

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

3 个答案:

答案 0 :(得分:3)

如果你知道你将要有多少循环和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

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

答案 1 :(得分: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

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

如果您想要随时构建列表,可以使用@ 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

答案 2 :(得分:1)

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需要这样一个冗长的习惯用法。同样令人沮丧的是,文档对于如何实现单元阵列是不透明的,以及附加到单元阵列是否昂贵。