Excel:计算与时间戳接近度配对的连续值
Excel: Counting Consecutive Values Paired With Time Stamp Proximity
我的问题
一些背景知识,我可以访问一个数据库,该数据库为我提供了带有时间戳的车辆的发动机状态代码。此引擎状态代码为十进制,但需要转换为二进制才能读取,因为每个引擎状态(无引擎速度、引擎降额等)都分配给 16 位中的一位。我已经弄清楚如何将这些十进制值转换为二进制,然后如何将二进制字符串拆分为单个单元格。我的数据现在看起来像这样:https://i.gyazo.com/359785dfe236b81d5545105dfc59a958.png.
这只是一个示例,值继续到第 8656 行。因此,E 列有时间戳,F 列有引擎状态(以十进制表示,即使它们看起来只有一个值,这些也会发生变化我提供的示例中的 1 或 65),G 列是 F 列转换为 16 位二进制,H 到 W 列是 G 列中字符串的每个单独位。黑框包含我需要隐藏的值,它们'被用作对上述数据库的查询的一部分。
现在,我想做的是计算 H 到 W 列中每一列满足以下两个条件的次数: (1) 该列中的值连续 5 次为 1或更多,以及 (2) 每个连续事件的时间戳(在 E 列中)彼此相隔两分钟以内。在这种情况下,满足这些条件的事件被认为是其中一个引擎状态实际上处于活动状态的事件,而不仅仅是一个短暂的信号。我需要为每个位列知道这一点。理想情况下,这些函数将位于位列上方的 H3:W3 中。作为参考,值数位于单元格 E6 中。
我试过的
我为条件(1)组合了以下函数,但它不起作用。我收到 #Value 错误。
=SUM(IF(FREQUENCY(IF(W7:W8656=1,COLUMN(W7:W8656)),IF(W7:W8656<>1,COLUMN(W7:W8656)))>=5,1))
对于时间戳我有这个:
=IF(E8 - TIMEVALUE("00:02:00")<E7,1,0)
它似乎可行,但我不太清楚如何实现它。它将与单个函数中的第一个函数配对(也许是 AND()?)
进行实验
如果您想仔细看看我正在处理的内容,我将我的工作表的净化版本上传到 Google 云端硬盘。这是一个 link:https://drive.google.com/open?id=0B_fZnVjXU9YAdS1JRS1VSnFnbmM.
编辑 1:
这是我在 G 列中使用的函数示例。
=DEC2BIN(INT(F7/256),8)&DEC2BIN(MOD(F7,256),8)
下面是我用来分割二进制字符串的内容:
第一个:
=VALUE(MID(G7,1,1))
第二个:
=VALUE(MID(G7,2,1))
等等。
好的。我认为这可能对你有用。要确定5个连续的位,可以将位的列与自身相加5次(起点和终点各偏移一行:
=W7:W8654+W8:W8655+W9:W8656+W10:W8657+W11:W8658
这将为您提供一个向量,其值为 0-5,具体取决于 5 位数据中 1 的数量。然后测试5个连续1的出现次数:
=SUM(IF(W7:W8654+W8:W8655+W9:W8656+W10:W8657+W11:W8658=5,1,0))
作为数组公式输入 (CTRL-ENTER)。
同样的逻辑适用于找到 4 个(不是 5 个——不要被差一错误所愚弄!) 2 分钟或更长的连续时间间隔。此公式计算 4 个连续间隔中有多少个 2 分钟间隔:
=IF(E8:E8655-E7:E8654>=TIME(0,2,0),1,0)+IF(E9:E8656-E8:E8655>=TIME(0,2,0),1,0)+IF(E10:E8657-E9:E8656>=TIME(0,2,0),1,0)+IF(E11:E8658-E10:E8657>=TIME(0,2,0),1,0)
要检测 4 个连续的 2 分钟间隔,您再次使用 =SUM(IF(...)) 公式:
=SUM(IF(IF(E8:E8655-E7:E8654>=TIME(0,2,0),1,0)+IF(E9:E8656-E8:E8655>=TIME(0,2,0),1,0)+IF(E10:E8657-E9:E8656>=TIME(0,2,0),1,0)+IF(E11:E8658-E10:E8657>=TIME(0,2,0),1,0)=4,1,0))
当连续1位和连续2分钟测试间隔同时出现时,这两个测试可以合并为一个大公式进行计数。
=SUM(IF(IF(E8:E8655-E7:E8654>=TIME(0,2,0),1,0)+IF(E9:E8656-E8:E8655>=TIME(0,2,0),1,0)+IF(E10:E8657-E9:E8656>=TIME(0,2,0),1,0)+IF(E11:E8658-E10:E8657>=TIME(0,2,0),1,0)=4,IF(W7:W8654+W8:W8655+W9:W8656+W10:W8657+W11:W8658=5,1,0),0))
顺便说一句,通过从连续1位开始到结束测试8分钟并忽略内部测试间隔,可以显着简化测试的时间方面。该更改可能会标记更多测试失败,因此您需要评估额外的失败是否真实。
这个解决方案有点乱,所以我希望我已经解释得足够好,希望它能有所帮助。
我会先说我没有为此使用数组公式,因此几乎可以肯定它会被简化。
请注意,为避免 #REF 错误或公式随行号而变化,我已将 headers 行显示在第 5 行,第一行数据出现在第 6 行。我'我们还根据时间戳(E 列)对数据进行了排序。这很重要,否则下面的第 2 步不起作用。
我的方法是使用大量辅助列。我已将问题分成四个单独的数据测试,每个测试有 16 列(每一位一列)。在所有情况下,每个公式都被复制到数据的底部并跨入每个 16 列的块中。
- 测试一个条件是否连续五次为1
X 到 AM 的列 - 公式 (X6):=IF(SUM(H2:H6)=5,1,0)
(跨列 X:AM 复制到数据集的底部)
- 测试前 5 个结果是否都在 2 分钟内出现window
列 AN 到 BC - 公式 (AN6):=IF(SUM($E6)-SUM($E2)<2/(24*60),1,0)
(跨列 AN:BC 复制到数据集底部)
- 测试以上两种情况是否出现在同一行
BD 到 BS 的列 - 公式 (BD6):=IF(AND(X6=1,AN6=1),1,0)
(跨列 BD:BS 复制到数据集的底部)
- 如果这两种情况都出现,则丢弃任何相邻的阳性结果(因此,如果在 1 分 30 秒内连续出现 5 个“1”,在 15 秒后又出现另一个 1,它仍被视为一个实例。
列 BT 到 CI - 公式 (BT6):=IF(AND(BD6=1,BD5<>1),1,0)
(跨列 BT:CI 复制到数据集的底部)
最后,您可以通过执行以下操作来检查每 16 个测试位的实例数:
单元格 H1 到 W1 - 公式 (H1):=COUNTIF(BT6:BT10628,1)
请注意,此公式的最后一行需要根据您的数据大小进行更改。
nickelcap,我又试了一下。这假设 (a) 时间戳数据位于从 $C$7 开始的列中; (b) 引擎状态代码位于从 $D$7 开始的列中,并且 (c) 数据可以向下延伸至第 8656 行。
一个。定义可接受的最小时间间隔(2 分钟)。在单元格 X1 中输入:
=TIME(0,2,0)
乙。在 X 列中创建一列增量时间数据(当没有数据时将值设置为零)。在单元格 X8 中输入:
=IF(LEN(TRIM($C8))=0,0,$C8-$C7)
并将此公式填写到第 8656 行。
C。创建一列二进制格式的引擎状态代码。这与您提出的公式相同,包含在过滤器中以在没有数据时将状态代码设置为全零。在单元格 G7 中输入:
=IF(LEN(TRIM(D7))>0,DEC2BIN(INT(D7/256),8)&DEC2BIN(MOD(D7,256),8),"0000000000000000")
并将此公式填写到第 8658 行。
D.范围 H7:W8658 与您提取单个位时使用的公式相同。例如。在 H7 中:
=VALUE(MID($G7,1,1))
E.最后,计算重复故障代码的公式。要计算列 H 事件的失败,我在 H4 中有这个:
=SUM(IF(IF($X:$X53<=$X,1,0)+IF($X:$X54<=$X,1,0)+IF($X:$X55<=$X,1,0)+IF($X:$X56<=$X,1,0)>=4,IF(H:H52+H:H53+H:H54+H:H55+H:H56>=5,1,0),0))
(不一定要在第 4 行——把它放在你想要的地方。)将该公式填入 W 列。
设置电子表格后,您可以清除 C 和 D 列中的旧数据和 copy/paste 新数据以分析新数据。
希望能助你一臂之力。
我的问题
一些背景知识,我可以访问一个数据库,该数据库为我提供了带有时间戳的车辆的发动机状态代码。此引擎状态代码为十进制,但需要转换为二进制才能读取,因为每个引擎状态(无引擎速度、引擎降额等)都分配给 16 位中的一位。我已经弄清楚如何将这些十进制值转换为二进制,然后如何将二进制字符串拆分为单个单元格。我的数据现在看起来像这样:https://i.gyazo.com/359785dfe236b81d5545105dfc59a958.png.
这只是一个示例,值继续到第 8656 行。因此,E 列有时间戳,F 列有引擎状态(以十进制表示,即使它们看起来只有一个值,这些也会发生变化我提供的示例中的 1 或 65),G 列是 F 列转换为 16 位二进制,H 到 W 列是 G 列中字符串的每个单独位。黑框包含我需要隐藏的值,它们'被用作对上述数据库的查询的一部分。
现在,我想做的是计算 H 到 W 列中每一列满足以下两个条件的次数: (1) 该列中的值连续 5 次为 1或更多,以及 (2) 每个连续事件的时间戳(在 E 列中)彼此相隔两分钟以内。在这种情况下,满足这些条件的事件被认为是其中一个引擎状态实际上处于活动状态的事件,而不仅仅是一个短暂的信号。我需要为每个位列知道这一点。理想情况下,这些函数将位于位列上方的 H3:W3 中。作为参考,值数位于单元格 E6 中。
我试过的
我为条件(1)组合了以下函数,但它不起作用。我收到 #Value 错误。
=SUM(IF(FREQUENCY(IF(W7:W8656=1,COLUMN(W7:W8656)),IF(W7:W8656<>1,COLUMN(W7:W8656)))>=5,1))
对于时间戳我有这个:
=IF(E8 - TIMEVALUE("00:02:00")<E7,1,0)
它似乎可行,但我不太清楚如何实现它。它将与单个函数中的第一个函数配对(也许是 AND()?)
进行实验
如果您想仔细看看我正在处理的内容,我将我的工作表的净化版本上传到 Google 云端硬盘。这是一个 link:https://drive.google.com/open?id=0B_fZnVjXU9YAdS1JRS1VSnFnbmM.
编辑 1:
这是我在 G 列中使用的函数示例。
=DEC2BIN(INT(F7/256),8)&DEC2BIN(MOD(F7,256),8)
下面是我用来分割二进制字符串的内容:
第一个:
=VALUE(MID(G7,1,1))
第二个:
=VALUE(MID(G7,2,1))
等等。
好的。我认为这可能对你有用。要确定5个连续的位,可以将位的列与自身相加5次(起点和终点各偏移一行:
=W7:W8654+W8:W8655+W9:W8656+W10:W8657+W11:W8658
这将为您提供一个向量,其值为 0-5,具体取决于 5 位数据中 1 的数量。然后测试5个连续1的出现次数:
=SUM(IF(W7:W8654+W8:W8655+W9:W8656+W10:W8657+W11:W8658=5,1,0))
作为数组公式输入 (CTRL-ENTER)。
同样的逻辑适用于找到 4 个(不是 5 个——不要被差一错误所愚弄!) 2 分钟或更长的连续时间间隔。此公式计算 4 个连续间隔中有多少个 2 分钟间隔:
=IF(E8:E8655-E7:E8654>=TIME(0,2,0),1,0)+IF(E9:E8656-E8:E8655>=TIME(0,2,0),1,0)+IF(E10:E8657-E9:E8656>=TIME(0,2,0),1,0)+IF(E11:E8658-E10:E8657>=TIME(0,2,0),1,0)
要检测 4 个连续的 2 分钟间隔,您再次使用 =SUM(IF(...)) 公式:
=SUM(IF(IF(E8:E8655-E7:E8654>=TIME(0,2,0),1,0)+IF(E9:E8656-E8:E8655>=TIME(0,2,0),1,0)+IF(E10:E8657-E9:E8656>=TIME(0,2,0),1,0)+IF(E11:E8658-E10:E8657>=TIME(0,2,0),1,0)=4,1,0))
当连续1位和连续2分钟测试间隔同时出现时,这两个测试可以合并为一个大公式进行计数。
=SUM(IF(IF(E8:E8655-E7:E8654>=TIME(0,2,0),1,0)+IF(E9:E8656-E8:E8655>=TIME(0,2,0),1,0)+IF(E10:E8657-E9:E8656>=TIME(0,2,0),1,0)+IF(E11:E8658-E10:E8657>=TIME(0,2,0),1,0)=4,IF(W7:W8654+W8:W8655+W9:W8656+W10:W8657+W11:W8658=5,1,0),0))
顺便说一句,通过从连续1位开始到结束测试8分钟并忽略内部测试间隔,可以显着简化测试的时间方面。该更改可能会标记更多测试失败,因此您需要评估额外的失败是否真实。
这个解决方案有点乱,所以我希望我已经解释得足够好,希望它能有所帮助。
我会先说我没有为此使用数组公式,因此几乎可以肯定它会被简化。
请注意,为避免 #REF 错误或公式随行号而变化,我已将 headers 行显示在第 5 行,第一行数据出现在第 6 行。我'我们还根据时间戳(E 列)对数据进行了排序。这很重要,否则下面的第 2 步不起作用。
我的方法是使用大量辅助列。我已将问题分成四个单独的数据测试,每个测试有 16 列(每一位一列)。在所有情况下,每个公式都被复制到数据的底部并跨入每个 16 列的块中。
- 测试一个条件是否连续五次为1
X 到 AM 的列 - 公式 (X6):=IF(SUM(H2:H6)=5,1,0)
(跨列 X:AM 复制到数据集的底部)
- 测试前 5 个结果是否都在 2 分钟内出现window
列 AN 到 BC - 公式 (AN6):=IF(SUM($E6)-SUM($E2)<2/(24*60),1,0)
(跨列 AN:BC 复制到数据集底部)
- 测试以上两种情况是否出现在同一行
BD 到 BS 的列 - 公式 (BD6):=IF(AND(X6=1,AN6=1),1,0)
(跨列 BD:BS 复制到数据集的底部)
- 如果这两种情况都出现,则丢弃任何相邻的阳性结果(因此,如果在 1 分 30 秒内连续出现 5 个“1”,在 15 秒后又出现另一个 1,它仍被视为一个实例。
列 BT 到 CI - 公式 (BT6):=IF(AND(BD6=1,BD5<>1),1,0)
(跨列 BT:CI 复制到数据集的底部)
最后,您可以通过执行以下操作来检查每 16 个测试位的实例数:
单元格 H1 到 W1 - 公式 (H1):=COUNTIF(BT6:BT10628,1)
请注意,此公式的最后一行需要根据您的数据大小进行更改。
nickelcap,我又试了一下。这假设 (a) 时间戳数据位于从 $C$7 开始的列中; (b) 引擎状态代码位于从 $D$7 开始的列中,并且 (c) 数据可以向下延伸至第 8656 行。
一个。定义可接受的最小时间间隔(2 分钟)。在单元格 X1 中输入:
=TIME(0,2,0)
乙。在 X 列中创建一列增量时间数据(当没有数据时将值设置为零)。在单元格 X8 中输入:
=IF(LEN(TRIM($C8))=0,0,$C8-$C7)
并将此公式填写到第 8656 行。
C。创建一列二进制格式的引擎状态代码。这与您提出的公式相同,包含在过滤器中以在没有数据时将状态代码设置为全零。在单元格 G7 中输入:
=IF(LEN(TRIM(D7))>0,DEC2BIN(INT(D7/256),8)&DEC2BIN(MOD(D7,256),8),"0000000000000000")
并将此公式填写到第 8658 行。
D.范围 H7:W8658 与您提取单个位时使用的公式相同。例如。在 H7 中:
=VALUE(MID($G7,1,1))
E.最后,计算重复故障代码的公式。要计算列 H 事件的失败,我在 H4 中有这个:
=SUM(IF(IF($X:$X53<=$X,1,0)+IF($X:$X54<=$X,1,0)+IF($X:$X55<=$X,1,0)+IF($X:$X56<=$X,1,0)>=4,IF(H:H52+H:H53+H:H54+H:H55+H:H56>=5,1,0),0))
(不一定要在第 4 行——把它放在你想要的地方。)将该公式填入 W 列。
设置电子表格后,您可以清除 C 和 D 列中的旧数据和 copy/paste 新数据以分析新数据。
希望能助你一臂之力。