我试图在我的数据集中获取每年的最大值。数据在一列中,按每日时间步长排列。如何从前 365 行中获取最大值,然后从接下来的 365 行中获取最大值?我在想类似的事情:
years=31;
for i=1:years
peak(i)=max(data(i:365*i,2))
end
但当 i=2 时,范围应为 366:730 等。数据矩阵是 11322x7 双倍,我需要第 2 列。
我想过建议像@Thilo's answer之类的东西,但这没有考虑闰年(它似乎出现在您的数据中,因为 365*31=11315,小于 11322)
您可能能够构建一个复杂的矢量化解决方案,但我很想手动跟踪开始和停止索引:
NYEARS = 31;
start = 1;
stop = 365 + isLeapYear(year(1));
n=1;
maxValues = nan(NYEARS,1);
while(n=<NYEARS)
maxValues(n) = max(data(start:stop,2));
n=n+1;
start = stop + 1;
stop = start + 365 + isLeapYear(year(n));
end
它可能不是非常快,但我怀疑这也将成为一个瓶颈。
function leap_p = isLeapYear(year)
leap_p = ~mod(year,400) || (~mod(year,4) && mod(year,100))
end
我怀疑这对你拥有的数据量很重要,但我想我想出了一个解决方案,包括闰年而不使用任何循环。因此,为了完整起见。我们将通过一个小例子再次建立这个想法,闰年有 11 天,正常的一年有 10 天。
data = 1:103
isLeapYear = [false, false, true, false, false, true, false, false, true, false]
你应该用 isLeapYear 函数的结果替换所有年份的向量。
接下来,我们生成一个包含 11 行(或者,在现实生活中是 366 行)和年数列的矩阵,其中仅包含值 1:
helpmatrix = ones(11, 10)
如果相应年份不是闰年,则将矩阵的最后一行设置为 0:
helpmatrix(end, ~isLeapYear) = 0
让我们将矩阵写成一个向量(使用如下所述的重塑)并总结所有的
selector = cumsum(reshape(helpmatrix, prod(size(helpmatrix)), 1))
我们可以使用这些值以每年有 11 (366) 天的方式炸毁我们的原始数据,我们可以使用下面的技巧。为了填充第 11 天的值,我们只需重用第 10 天的值,这既不会改变最大值,也不会改变最小值。(但请注意:其他功能也可能受此影响!)
max(reshape(data(selector), 11, length(selector)/11))
要转换它,您只需用 365 和 366 交换所有 10 和 11,并使用data(selector, 2)
而不是更改最后一个命令data(selector)
。
与循环解决方案相比,这可能并没有太大的好处,但它显示了矢量计算的力量。
您可以在更简单的基础上做到这一点。
该函数reshape
允许您将向量(或矩阵,如有必要)转换为另一个行/列布局。
您的问题可以通过以下方式解决
max(reshape(data(:,2), 365, length(data)/365))
为了了解发生了什么,我创建了一个较小的示例:
data = 1:100
reshape(data, 10, length(data)/10)
max(reshape(data', 10, length(data')/10))
您上面的循环也可以工作,但效率低下。您必须注意如何创建索引。你做i:365*i
。在我上面的例子中,这看起来像
for i=1:10
i:10*i
end
这显然不是你想要的。以你能做的正确方式完成
for i=1:10
(10*(i-1) + 1):10*i
end
希望有帮助。