【问题标题】:From find function to nested loops从查找函数到嵌套循环
【发布时间】:2015-02-20 21:09:54
【问题描述】:

文件lake_powell.dat 包含2000 年至2007 年8 年的水库水位数据。这些数据如表8.9 所示。使用文件中的数据回答下列问题: (a) 确定每年和收集数据的 8 年期间的平均水位高度。 (b) 确定每年有多少个月超过 8 年期间的总体平均值。 (c) 创建一份报告,列出超过总体平均值的每个月份的月份(数字)和年份。例如,六月是第 6 个月。 (d) 确定 8 年期间每个月的平均水位。

原来,我在学习 find 功能时有这个问题。对此,我得到了答案:

load LAKE_POWELL.DAT

% part a
table=[LAKE_POWELL]; % Puts LAKE_POWELL.DAT into a table
yearly=mean(table) % Finds the average elevation of the water level for each year
eight_years=mean(table(:)) % Puts the values of the matrix into one column vector before finding the average the entire matrix
    % part b
l=[eight_years] % Puts averages into matrix
i=mean(table) % Finds overall average of data
[y]=(find(table>i)) % Finds which months are above overall average

% part c
fprintf('Month # %f in year %f exceeds overall average',y,column) % Creates a report that lists the month and the year for each of the months that exceed the overall average


% part d
months=table'; % Transposes the table so that the months are now columns
per_month=mean(months) % Determines the average elevation of the water for each month

但现在有人告诉我,我需要使用嵌套循环解决相同的问题。到目前为止,我有:

    load LAKE_POWELL.DAT

table=[LAKE_POWELL];


for k=1:length(table)
    a=mean(table(k))
    eight_year=mean(a)

    b=zeros(1,length(table))
    for k=1:length(table)
        b(k)=find(table>eight_year)
    end
end

当然,它不起作用。你有什么建议吗?

【问题讨论】:

  • 您不能在两个嵌套的 for 循环中使用相同的索引变量。尝试将第二个“for k”改为使用“j”。
  • @such 我一直报错:在赋值 A(I) = B 中,B 和 I 中的元素个数必须相同。
  • 如何调试这样的错误。在 Matlab 中:启用错误停止。运行脚本直到它失败。然后,您将看到它在哪一行失败,以及回溯。然后计算左侧参数的值和右侧参数的值。

标签: matlab


【解决方案1】:

按照我理解您的数据的方式,您有一个包含 12 行(每个月一个)和一个 8 列(每年一个)的矩阵。 首先,您需要学习从矩阵中读取值并将值分配给矩阵。 对于从1length(table) 的每个整数值,for 循环for k = 1:length(table) ... end 运行for k = 1:length(table)end 之间的所有代码(这里你应该注意到length(table) 给你最大维度的长度table(这里是12 - 我猜这不是你想要的))。除了length(table),您可以使用size(table,1) 来表示行数,使用size(table,2) 来表示列数。

所以在for 循环的每次迭代中,k 是一个数字。如果您只是将一个数字放入矩阵中,它只会为您提供矩阵的一个条目,更准确地说是kth 列向量中的条目,该条目由按顺序排列的矩阵列组成,例如在您的 12x8 矩阵条目中,15 将是表格第三行和第二列中的条目 - 即 table(15)table(3,2) 相同(当表格具有这些尺寸时)。

要获取整行或整列,您需要使用向量进行索引或使用:-运算符。这很容易做到:table(i,:) 为您提供表格的ith 行,table(:,j) 为您提供表格的jth 列。你对a=mean(table(k)) 行所做的是将a 设置为tablekth 条目的平均值(这是单个数字的平均值 - 所以a = table(k))。您可能要做的是将akth 条目设置为tablekth 列的平均值:a(k) = mean(table(:,k));。然后下一行是正确的,除了您计算到目前为止每个步骤的结果的均值,而不是在其他计算完成后仅计算一次均值。

现在我们遇到问题 b。首先,正如评论中所解释的那样,您永远不应该在嵌套循环中使用与循环变量相同的变量! Matlab 会允许,但您很可能会从计算中得到错误的结果!

您收到错误的原因是b(k) 是对向量中单个条目的引用,而find(table>eight_year) 可能会为您提供从095 的任何元素。有很多不同的方法可以解决这个问题!我建议您使用您的代码尝试一次只运行小段(可以通过选择要运行的行然后按 F9 来完成)。尝试了解logical 矩阵是什么(查看table>eight_year 的结果,尝试定义一些额外的变量来帮助您。并使用您使用的不同函数的文档(选择函数名称并按F1),希望这能帮助您自己解决问题。

您应该知道,您的代码中的错误比我提到的要多。有些错误更容易找到,例如当您执行 Matlab 中不允许的操作时,它会告诉您错误发生在哪一行。但是你的大部分错误实际上是你计算出你想要的东西之外的东西。所以试着坐下来真正理解你的代码的每一步,这样你以后会容易得多。

【讨论】:

  • 非常感谢您抽出宝贵时间为我输入此内容。它真的帮助我理解了我做错了什么以及我需要做什么来回答这个问题。谢谢!