Python 检测数据帧中两列的重叠信号事件

Python 检测数据帧中两列的重叠信号事件,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个包含两列a和B的数据帧。a和B中的值可以是0.0或1.0(二进制状态) 信号大部分时间都为0.0,偶尔为1.00。我想检测A和B都为1.00且重叠(内部连接)的每个事件 下面是一个示例代码: import numpy as np import pandas as pd from matplotlib import pyplot as plt from pandas.plotting import register_matplotlib_converters register_matplo

我有一个包含两列a和B的数据帧。a和B中的值可以是0.0或1.0(二进制状态)

信号大部分时间都为0.0,偶尔为1.00。我想检测A和B都为1.00且重叠(内部连接)的每个事件

下面是一个示例代码:

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
%matplotlib inline
np.random.seed(101)

data = np.zeros((1200,2),dtype=float)

df = pd.DataFrame(data=data,
                  index=pd.date_range('2020-05-19', 
                  freq='50ms', periods=1200),
                  columns=['A','B'])
#event1
df.loc[pd.to_datetime('2020-05-19 00:00:01.000'):pd.to_datetime('2020-05-19 00:00:02.500'),'A'] =1.00
df.loc[pd.to_datetime('2020-05-19 00:00:01.500'):pd.to_datetime('2020-05-19 00:00:03.000'),'B'] =1.00
#event2
df.loc[pd.to_datetime('2020-05-19 00:00:12.000'):pd.to_datetime('2020-05-19 00:00:15.000'),'A'] =1.00
df.loc[pd.to_datetime('2020-05-19 00:00:13.000'):pd.to_datetime('2020-05-19 00:00:14.500'),'B'] =1.00
#event3
df.loc[pd.to_datetime('2020-05-19 00:00:40.000'):pd.to_datetime('2020-05-19 00:00:43.000'),'A'] =1.00
df.loc[pd.to_datetime('2020-05-19 00:00:42.000'):pd.to_datetime('2020-05-19 00:00:46.000'),'B'] =1.00
A和B的线图,以显示重叠。注:我已将A移动了0.01,以使所有线条可见

def plot_Class_AB():
    fig, ax = plt.subplots(nrows=1,ncols=1,figsize=(15,4))
    ax.set_title("Checking overlaps of A and B")

    ax.plot(df['A'].dropna()+0.01,label="A",color='red')
    ax.plot(df['B'].dropna(),label="B",color='blue')
    ax.set_ylabel("Class")
    ax.legend()

我可以获得第一个事件的开始时间和最后一个事件的结束时间,如下所示

events_startTime = df[(df['A'] == 1.00)  & (df['B'] == 1.00)].head(1).index
events_endTime   = df[(df['A'] == 1.00)  & (df['B'] == 1.00)].tail(1).index
print('events_startTime:',events_startTime)
print('events_endTime:  ',events_endTime)
然而,我对个别事件重叠的时间安排感兴趣。我的预期输出与此类似:

event1_startTime = 2020-05-19 00:00:01.500
event1_endTime:  = 2020-05-19 00:00:02.500

event2_startTime = 2020-05-19 00:00:13.000
event2_endTime:  = 2020-05-19 00:00:14.500

event3_startTime = 2020-05-19 00:00:42.000
event3_endTime:  = 2020-05-19 00:00:43.000

你能提出解决这个问题的办法吗?

把两个信号相乘,找出乘积不为零的索引怎么样

import numpy as np

a = df['A'].dropna().values
b = df['B'].dropna().values

events_idxs = np.where(a*b > 0.5)[0]

(我设置了一个0.5的阈值,因为看起来你的信号在事件之外并不完全是0)

我使用了JacoSolari的建议,该建议返回了所有指数的列表,其中a==B==1.00。对于上面的示例,它返回以下数组:

array([ 30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
        43,  44,  45,  46,  47,  48,  49,  50, 260, 261, 262, 263, 264,
       265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277,
       278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290,
       840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852,
       853, 854, 855, 856, 857, 858, 859, 860], dtype=int64)
最后,我添加了下面的函数,该函数从上面的数组中提取所有事件的开始和停止索引列表。代码如下

def find_start_stop_indexes(df):

    a = df['A'].dropna().values
    b = df['B'].dropna().values

    events_idxs = np.where(a*b > 0.5)[0]

    if len(events_idxs) > 0:

        # initiate a list to store first,last index of each event
        first_last = [events_idxs[0]]
        i = 1
        while i < len(events_idxs):
            if (events_idxs[i] - events_idxs[i-1]) < 2:   
                i = i+1
                if i == len(events_idxs):
                    first_last.append(events_idxs[i-1])
            else:
                first_last.append(events_idxs[i-1])
                first_last.append(events_idxs[i])
                i = i +1
                if i == len(events_idxs):
                    first_last.append(events_idxs[i-1])

        return(first_last)
    else:
        return([])
不确定是否有更简单的解决方案,但它是有效的

[30, 50, 260, 290, 840, 860]