查找定义事件的连续天数

时间:2014-06-10 20:36:13

标签: matlab

我目前正在寻找一种方法来使用Matlab来帮助定义某个站点的热浪事件。对于我的情况,热浪是高温或低温的正常偏离在95%(a"放松"热波)或99%(a"严格"热浪)。

我使用了具有每日最高和最低温度的.csv文件,以及各自的离开。从这里我能够将数据分解为我想要的时间范围,然后计算阈值。有四种不同的阈值 - 95%的最小和最大温度偏离以及99%的最小和最大温度偏离。

目前我有四个矩阵,每个矩阵都有各自阈值的数据。以下是满足最高温度偏离阈值(m1)的矩阵的一小部分:

694158    99    14    64    1
694159    99    13    68    5
694179    98    13    63    1
694180    98    14    74   12
694183   100    16    70    8

第一列代表序列日期编号,其余列是温度信息(最大,最大离开,最小,最小离开)。

所以这是我的问题:我找不到一种方法来查看序列日期编号,看看连续几天是否连续三天(或更多)。

我在网上找到的最佳帮助是this mathworks post,但解决方案不会将任何信息附加到矩阵中。

如果有人能指出我正确的方向,或指向我的资源来帮助我,我会非常感激!

提前致谢。

3 个答案:

答案 0 :(得分:1)

M表示您的矩阵,n表示您想要的最小连续天数(在您的示例中为3)。然后:

ind = find(conv(double(diff(M(:,1))==1), ones(n-1,1))==n-1)-n+2; %// starts
ind = bsxfun(@plus, ind, 0:n-1); %// fill n-1 subsequent row indices
ind = unique(ind(:)); %// make unique
result = M(ind,:); %// keep only those rows

答案 1 :(得分:0)

查看您的评论,您希望找到具有三个或更多连续日期的行。基本算法是我们有一个大小为3的滑动窗口。我们检查最后一个点和第一个点之间的差异是否 2 。例如,694160和694158之间的差异为2,这表示连续3天。每当我们看到差异为2时,这意味着这三行表示连续运行。

我们可以使用im2col函数实现这个滑动窗口机制。这是假设您已安装图像处理工具箱(交叉手指)。然后我们可以将我们的日期数组分割成重叠的3组。然后我们实现上面的逻辑,看看哪些区域有2的差异。此时,这些位置表示起始位置连续运行的地方。请记住,如果要捕获> 3的连续运行,我们将重复运行。例如,如果我们有一个4的运行(假设从694158到694162),我们将在1到3和2到4的位置运行。然后我们将需要消除重复,以便我们最终可以捕获我们的唯一行。不用多说,这里有一些代码示例。这是我要使用的例子。假设A是您从矩阵中提取的日期列。我在这里人为地创建它以使示例自成一体。

A = [(694158:694160)'; 694161; 694179; 694180; 694183; (694160:694162)';(695000:695005)'];

A =

  694158
  694159
  694160
  694161
  694179
  694180
  694183
  694160
  694161
  694162
  695000
  695001
  695002
  695003
  695004
  695005

现在,这是我实施的逻辑:

%//Place our array into neighbourhoods of 3
columns = im2col(A, [3, 1]);
%//Find the difference
diffColumns = bsxfun(@minus, columns, columns(1,:));
%// Check to see which columns have a max difference of two
maxDiff = find(diffColumns(3,:) == 2);
%//Find those rows that satisfy our condition
rowsNonUnique = arrayfun(@(x) x:x+2, maxDiff, 'UniformOutput', false);
% // Eliminate duplicates and transform back
rowsFinal = unique(cell2mat(rowsNonUnique));

rowsFinal =

Columns 1 through 12

 1     2     3     4     8     9    10    11    12    13    14    15

Column 13

 16

从数据中可以看出,我们需要1-4行和8-16行,因为它与我们知道的至少3行或更多行的连续行一致。

现在,如果您想将此附加到上面的矩阵中,则可以执行以下操作,假设您的数据存储在变量matrix

indicator = zeros(size(matrix,1),1);
indicator(rowsFinal) = 1;
matrix(:,6) = indicator;

这将创建第六列,而这将显示具有1值的任何内容,这意味着这是您需要考虑的行,而0表示您跳过它。

祝你好运!

答案 2 :(得分:0)

在这里,你应该这样做:

count = 0;
for ii = 2:size(tempArray, 1)
    if tempArray(ii, 1) == (tempArray(ii-1, 1)+1)
        count = count + 1;
        if count >= 3;
            tempArray(ii-2:ii, 6) = 1;
        end 
    else
        count = 0;
    end 
end
%// This last line should work... but I haven't tested it.
consecArray = tempArray(find(tempArray(:,6)==1));

代码遍历数组的每个元素,将其与前一个元素进行比较,如果发现连续三个是顺序的,则将第六行设置为1.因此,在运行此脚本之后,您将拥有一个矩阵其中,作为三个或更多连续日的一部分的每一行将具有表示尽可能多的值。