function [res1] = matprec()
res1 = [
1,2001,1,2,0.00;
1,2001,1,5,5.33;
2,2001,1,5,4.57;
3,2001,1,5,5.33;
4,2001,1,5,5.59;
5,2001,1,5,4.32;
2,2001,1,13,0.00;
3,2001,1,13,0.00;
4,2001,1,13,0.00;
3,2001,1,30,30.73;
2,2001,2,1,1.02;
3,2001,2,1,1.52;
4,2001,2,1,1.78;
5,2001,2,1,1.27;
1,2001,2,2,1.78;
2,2001,2,2,1.27;
3,2001,2,2,1.78;
4,2001,2,2,2.03;
5,2001,2,2,1.78;
1,2001,3,4,18.03;
3,2001,3,4,15.75;
5,2001,3,4,17.53;
1,2001,3,5,13.46;
2,2001,3,5,12.19;
3,2001,3,5,11.94;
4,2001,3,5,9.65;
5,2001,3,5,10.92;
2,2001,4,30,0.00;
4,2001,4,30,0.00];
format short g
return
endfunction
所以在这个矩阵中,第一列只是我们测量降水量的站,第二列是年,第三列是月,第四列是日,第五列是降水量。我想在另一个文件中做的是调用这个矩阵并进行以下微积分,在第1个月我想做所有日子的平均值,例如:
在第1天第5天我有5个值5.33,4.57,5.33,5.59,4.32,所以我会这样做
(5.33 + 4.57 + 5.33 + 5.59 + 4.32)/ 5 = 5.028
而且我想在所有的日子里这样做,当我有所有的日子时,我会把它们全部加在一起,以了解当月的降水量,并在4个月内完成。
这就是程序应该如何运作,我已经用这段代码完成了这个:
Result = matprec();
month1Indices = Result(:,3) == 1;
month1Rows = Result(month1Indices, :);
day5Indices = month1Rows(:,4) == 5;
day5Rows = month1Rows(day5Indices , :);
mean(day5Rows(:,5));
Result2 = matprec();
month1Indices2 = Result2(:,3) == 1;
month1Rows2 = Result2(month1Indices2, :);
day5Indices2 = month1Rows2(:,4) == 30;
day5Rows2 = month1Rows2(day5Indices2 , :);
mean(day5Rows2(:,5));
mes1 = mean(day5Rows(:,5)) + mean(day5Rows2(:,5));
lol = [mes1, mes2, mes3, 0, 0, 0, 0, 0, 0, 0, 0, 0];
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
plot(x,lol);
但这只适用于第一个月,所以我正在尝试做一个循环来完成所有月份和所有的一天并绘制它,我有这个,但它只是永远地继续:
a = 1
b = 1
while (a <= 4 && b <= 30)
Result = matprec();
month1Indices = Result(:,3) == a;
month1Rows = Result(month1Indices, :);
day5Indices = month1Rows(:,4) == b;
day5Rows = month1Rows(day5Indices , :);
mean(day5Rows(:,5))
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
plot(x,mean(day5Rows(:,5)));
endwhile
Sory我知道它有点长,但我需要解释一下,谢谢。
答案 0 :(得分:0)
我重写了一下,因为我认为你通过使用这么多不同的变量和数值的硬编码来过度复杂化。通常,更容易提取您所需的内容:
months = res1(:, 3);
prec = res1(:, 5);
m_start = 1; # month where to start averaging
m_end = 4; # month where to end averaging
# prepare output vector
avg = zeros(m_end - m_start + 1, 1);
for m = m_start:m_end
temp = prec(months == m);
avg(m) = mean(temp);
end
plot(avg)
grid
在您的示例中,您只使用了非零值,这是有意的吗?如果你想要这种行为,我建议使用一个小的epsilon值作为阈值:
for m = m_start:m_end
temp = prec(months == m);
# --------------------------
# ignore smaller values
eps = 1e-12;
temp = temp(temp > eps);
# --------------------------
avg(m) = mean(temp);
end
答案 1 :(得分:0)
您描述的计算有点令人困惑。我假设第一步是确定一个月内每天的平均降水量(在车站上取平均值)
mean_precipitation = accumarray([res1(:,3), res1(:,4)], res1(:,5), [], @mean);
矩阵的每一行对应一个月,每列一天。 accumarray函数执行您在循环中执行的大部分工作。第一个参数[res1(:,3), res1(:4)]
是一个两列矩阵,其中第一列指定月份(行),第二列指定每个“累积”结果所属的日期(列)。第二个参数res1(:,5)
是每个最终结果中“累积”的值,最后一个参数@mean
是应用于每个月日数据集合的累积函数的类型。有关替代说明(或谷歌)的信息,请参阅help accumarray
- 最初它的工作原理可能有点令人困惑。
计算中的下一步有两种不同的解释。
如果您想要一个月内 降水的天数的平均降水量,那么:
sum(mean_precipitation, 2) ./ sum(mean_precipitation > 0, 2)
ans =
17.8790
1.5627
14.3677
NaN
这将给出最后一个月的NaN,因为没有记录降水的天数,因此没有定义平均值。
如果您想要本月所有天的平均降水量,那么您需要计算每个月的天数。这可以通过eomday()
找到(我假设所有观察都在2001年),那么计算就是
sum(mean_precipitation, 2) ./ eomday(2001, (1:size(mean_precipitation, 1))')
ans =
1.15348
0.11162
0.92695
0.00000
希望这能为您提供有关如何执行计算的一些想法。
虽然循环是一种较旧的命令式编写代码。有时它们对于清晰度是有用的,但有时它们比使用可能“计算”计算的已建立函数要慢(参见Why does vectorized code run faster than for loops in MATLAB?)