gpt4 book ai didi

matlab - 在Matlab中检查时间戳记间隔

转载 作者:行者123 更新时间:2023-12-01 12:40:21 24 4
gpt4 key购买 nike

我只是想知道是否有一种方法可以比较许多时间戳,以查看是否缺少任何时间戳。
目前,我每年要看365天,每天要读取48个读数。 (在Excel文档中)因此我需要分析17000多点。
目前,时间戳记的格式为:

1/01/2011 12:30 AM
1/01/2011 1:00 AM
1/01/2011 1:30 AM
1/01/2011 2:00 AM
1/01/2011 2:30 AM

我需要检查每30分钟是否缺少任何值。我已经考虑过使用
datenum('')

然后尝试比较它,如果它不遵循趋势,则抛出错误并返回先前的值。但是我不确定。

任何帮助,将不胜感激!

最佳答案

您可以使用datenum并放入您提供的示例中确切的日期格式的字符串之一。如果您有半小时的时间间隔,则连续datenum调用之间的差异应该产生相同的差异。例如,让我们将日期放入像这样的单元格数组中:

C = {'1/01/2011 12:30 AM',
'1/01/2011 1:00 AM',
'1/01/2011 1:30 AM',
'1/01/2011 2:00 AM',
'1/01/2011 2:30 AM'};

我们可以使用 diff 来获取连续元素之间的差异。给定数组中的第i个元素, diff的工作原理,给定输入值 y_i的情况下 x_i处矢量的输出为:
y_i = x_{i+1} - x_i

因此,这将返回其长度比原始长度短一的向量。我们基本上正在考虑从日期的第二个元素开始的元素。这样,对于此单元格数组中的每个元素,将 diff应用于 datenum,我们得到:
format long
diffs = diff(datenum(C))

diffs =

0.020833333255723
0.020833333372138
0.020833333372138
0.020833333255723

前7位有效数字左右很重要。其余数字是由于一些精度差异而引起的,但现在暂时将其搁置。因此,您需要检查差异中的每个元素是否都与 0.0208333有关。如果不是,则您错过了一个间隔。让我们尝试几次:
C = {'1/01/2011 12:30 AM',
'1/01/2011 1:30 AM',
'1/01/2011 2:30 AM',
'1/01/2011 3:00 AM',
'1/01/2011 4:30 AM'};

format long
diffs = diff(datenum(C))

diffs =

0.041666666627862
0.041666666627862
0.020833333372138
0.062500000000000

因此,对于 C的第二,第三和最后一个元素,我们在半小时间隔内缺少测量值。具体来说,我假设您的单位是半小时。这样,在丢失的测量之间可能发生的最小跳跃是一个小时,这就是 0.02080.0416之间的跳跃,因此大约是 0.02的差异。因此,我们需要在此数组中找到比 0.0416大的位置。为了安全起见,我们将其设置为 0.03。因此,如果要以编程方式执行此操作,则可以执行以下操作:
diffs = diff(datenum(C));
locs = find(diffs > 0.03) + 1;

find 找出满足特定布尔条件的矩阵/数组中的位置。在这种情况下,我们要查找差异为 > 0.03的位置。我们也用 1抵消了,因为我们正在像前面讨论的那样看第二个元素。通过修改后的 C数组执行此操作,我们得到:
locs =

2
3
5

这告诉我们,在修改后的日期数组( C)的位置2、3和5,我们在半小时标记处缺少测量值。

为了仔细检查我们的第一个示例,如果我们在没有跳过的情况下将其应用于第一个示例,我们将得到预期的空数组:
locs = 

[]

另外,我们可以显示缺少间隔的位置。特别:
missingTimes = C(locs)

对于我们的时间错乱的示例,我们得到:
missingTimes = 

'1/01/2011 1:30 AM'
'1/01/2011 2:30 AM'
'1/01/2011 4:30 AM'

编辑

从我们在评论中的对话中,一旦您有一个没有时间的日期而只有日期的日期,这就会变得混乱。具体来说,当您在单元格数组中使用至少其中之一调用 datenum时,将不再获得浮点精度。我们只会得到整数(出于某些奇怪的原因……我不知道为什么。我可能应该对此发表一个StackOverflow帖子)。换句话说,如果我们这样做:
C = {'1/01/2011',
'1/01/2011 12:30 AM',
'1/01/2011 1:30 AM',
'1/01/2011 2:30 AM',
'1/01/2011 3:00 AM',
'1/01/2011 4:30 AM'};

如果我们这样做:
diff(datenum(C))

我们得到:
ans =

0
0
0
0
0

为了解决这个问题,我必须实现自己的 diff版本,并分别访问dates数组中的元素。因此,请执行以下操作:
format long;
diffs = arrayfun(@(x) datenum(C{x}) - datenum(C{x-1}), (2:numel(C)).');

我使用了 arrayfun ,并指定了一个输入数组,该数组从2到 C中的元素数量一样多。对于输出中的每个元素,我们采用 datenum th元素的 i+1表示形式,并将其从 i th元素中减去。这本质上是手动实现 diff操作,并且当您包含没有时间的日期时,可以逃避轻微的错误。老实说,我不知道为什么要删除所有数字后的所有小数点....但是现在可以使用。

无论如何,我们得到:
diffs =

0.020833333372138
0.041666666627862
0.041666666627862
0.020833333372138
0.062500000000000

编辑#2

看来您仍然遇到麻烦。我要提出的另一个建议是找到那些 时间戳丢失了的时间。然后,我们将找到这些条目并手动放置 12:00 AM时间戳。这样,我们可以使用正则表达式通过 12:00 AM 来实现。正则表达式尝试查找字符串中模式出现的位置。这样,我们将要做的事情是找到那些 不在末尾包含时间戳的模式,然后使用一些附加代码将此时间戳插入其中。让我们来看一个玩具示例:
C = {'1/01/2011',
'1/01/2011 12:30 AM',
'1/01/2011 1:30 AM',
'1/01/2011 2:30 AM',
'1/01/2011 3:00 AM',
'1/01/2011 4:30 AM',
'1/02/2011',
'1/02/2011 12:30 AM',
'1/02/2011 1:30 AM',
'1/02/2011 2:30 AM',
'1/02/2011 3:00 AM',
'1/02/2011 4:30 AM',
'1/03/2011',
'1/03/2011 12:30 AM',
'1/03/2011 1:30 AM',
'1/03/2011 2:30 AM',
'1/03/2011 3:00 AM',
'1/03/2011 4:30 AM'};

在这里,我们有各种日期和时间,有些缺少 regexp时间戳。因此,这是我要在其中插入时间戳的方法:
missingTimeStampsLocs = cellfun(@(x) isempty(regexp(x,'[0-9]{1,2}\/[0-9]{2}\/[0-9]{4} [0-9]{1,2}:[0-9]{2} [AaPp][Mm]')), C);
missingTimeStamps = C(missingTimeStampsLocs);
filledInTimeStamps = cellfun(@(x) [x ' 12:00 AM'], missingTimeStamps, 'uni', 0);
C(missingTimeStampsLocs) = filledInTimeStamps;

这看起来有些令人生畏,但可以肯定地解释。让我们从第一行代码开始。首先,我们在其想要输入的字符串中调用 12:00 AM,然后第二个参数用于描述您正在寻找的 模式。我要做的是按照以下格式查找所有日期:
 #/##/#### ##:## xx
OR
##/##/#### ##:## xx
regexp表示数字,而 #表示字符。我们将搜索所有遵循 确切格式的日期。任何不遵循此格式的日期都将标记出来,这意味着它们缺少时间戳。看一下以下语句:
regexp(x,'[0-9]{1,2}\/[0-9]{2}\/[0-9]{4} [0-9]{1,2}:[0-9]{2} [AaPp][Mm]')

这就是说,对于字符串 x,我们将查找以1或2个数字开头的字符串,然后是 x,然后是正好2个数字,然后是 /,接着是正好4个数字,然后是一个空格,那么我们将查找1或2个数字,然后是 /,然后是正好2个数字,然后是一个空格,然后是 :AM,并且是 不区分大小写的。这意味着 PMAM可以为大写或小写。

PM返回的内容是您的字符串中 位置的位置(找到此字符串)。在我们的例子中,它将返回 regexp,这意味着我们已经在字符串 处找到了该字符串,或者返回的空,这意味着我们没有找到这样的字符串。如果1返回空,则该日期缺少时间戳。这就是为什么我用 regexp 包裹此调用以检查isempty是否返回空的原因。然后,我使用 regexp 封装此调用,以便我们可以迭代日期单元格数组中的所有元素。输出(存储在cellfun中)将包含一个布尔数组,其中missingTimeStampsLocs表示缺少时间戳,而1表示没有时间戳。

然后,下一行代码从原始单元格数组中提取缺少日期的那些日期。然后,我再运行一次0以遍历这些单元格,然后在提取的单元格数组中每个字符串的末尾连接cellfun时间戳。请注意,我还指定了两个附加参数(12:00 AM'uni'),因为输出不再是单个值,而是一个字符串。这些字符串将放置在单元格数组中,这是完美的,因为无论如何它们都是从单元格数组中提取的。我们不必在第一个0调用中指定它,因为输出是单个值-在这种情况下,它是cellfun0的布尔值。完成后,我们将那些缺少时间戳的日期替换为我们刚刚用1时间戳填写的日期。这将被覆盖为12:00 AM。这样,通过使用C运行上面的代码,我们得到的是:
C =  

'1/01/2011 12:00 AM'
'1/01/2011 12:30 AM'
'1/01/2011 1:30 AM'
'1/01/2011 2:30 AM'
'1/01/2011 3:00 AM'
'1/01/2011 4:30 AM'
'1/02/2011 12:00 AM'
'1/02/2011 12:30 AM'
'1/02/2011 1:30 AM'
'1/02/2011 2:30 AM'
'1/02/2011 3:00 AM'
'1/02/2011 4:30 AM'
'1/03/2011 12:00 AM'
'1/03/2011 12:30 AM'
'1/03/2011 1:30 AM'
'1/03/2011 2:30 AM'
'1/03/2011 3:00 AM'
'1/03/2011 4:30 AM'

然后,我们可以通过检测代码运行此命令,并查看哪些日期跳了半个小时。
diffs = diff(datenum(C));
locs = find(diffs > 0.03) + 1;
missingTimes = C(locs)

因此,我们得到:
missingTimes = 

'1/01/2011 1:30 AM'
'1/01/2011 2:30 AM'
'1/01/2011 4:30 AM'
'1/02/2011 12:00 AM'
'1/02/2011 1:30 AM'
'1/02/2011 2:30 AM'
'1/02/2011 4:30 AM'
'1/03/2011 12:00 AM'
'1/03/2011 1:30 AM'
'1/03/2011 2:30 AM'
'1/03/2011 4:30 AM'

我真的希望这是我最后一次解决这个问题(LOL),因为我很确定我已经涵盖了所有意外情况。我还假设您的日期是以特定方式格式化的,并且希望这可以解决您的问题。我们也不需要使用我们编写的自定义C函数,因为我现在要完成您的日期以在上面加上diff时间戳。

祝好运!

关于matlab - 在Matlab中检查时间戳记间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25478989/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com