索引移动范围

时间:2012-05-06 05:03:56

标签: matlab indexing

我试图在我的数据集中获取每年的最大值。数据在一列中,按每日时间步顺序排列。 如何从前365行获得最大值,然后从接下来的365行获得最大值? 我想的是:

years=31;
for i=1:years
peak(i)=max(data(i:365*i,2))
end

但是当i = 2时,范围应该是366:730,依此类推。 数据矩阵是11322x7双倍,我需要第2列。

2 个答案:

答案 0 :(得分:2)

我想过建议像@ Thilo这样的答案,但这并没有考虑闰年(这似乎出现在您的数据中,因为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

答案 1 :(得分:1)

包括闰年的更新

我怀疑你拥有的数据量是多少,但我想我想出了一个包含闰年而不使用任何循环的解决方案。因此,为了完整起见。我们将通过一个小例子再次建立这个想法,其中闰年有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

希望有所帮助。

相关问题