尝试使用熊猫来操纵传感器时间数据



我正在尝试查看是否有办法使用Pandas进行以下计算:

我有一个表格,其中包含事件编号,后跟它们各自的开始和结束日期时间。

Event Number    Start            End
1      6/1/2020 13:00  6/1/2020 13:30
2      6/1/2020 17:45  6/1/2020 19:15
3      6/4/2020 8:00   6/4/2020 9:10
4      6/7/2020 11:00  6/7/2020 11:50

另外,我还有另一个表,其中包含每个传感器的原始时间索引数据

Datetime    Sensor 1     Sensor 2    Sensor 3
6/1/2020 0:00     80           4           0
6/1/2020 0:01     80           5           0
6/1/2020 0:02     69           9           1
6/1/2020 0:03     72           8           0
6/1/2020 0:04     60           9           0
6/1/2020 0:05     76           3           0
6/1/2020 0:06     62           8           1
6/1/2020 0:07     80           8           0
6/1/2020 0:08     64           7           1

有没有办法让我运行原始表并根据 START 和 END 时间戳裁剪这个表?

我正在尝试最终表看起来像什么,包括

  • 打开
  • 关闭
  • 最小值
  • 麦克斯
  • 意味 着

这些日期之间的所有传感器。

我尝试使用for循环没有太多运气,但它需要很长(+3M行原始数据(。

有没有办法对熊猫做到这一点?

提前感谢大家

编辑 1:添加了我想到的输出作为澄清:

Event   Type    Sensor 1    Sensor 2    Sensor 3
1     Open       60          5           1
1     Close      69          8           0
1     Max        78          8           1
1     Min        59          4           0
1     Mean       69          8           0.333
2     Open       77          4           0
2     Close      73          6           1
2     Max        77          6           1
2     Min        68          4           0
2     Mean       74          6           0.667 
3     Open       63          4           1
3     Close      71          7           1
3     Max        70          8           1
3     Min        63          3           0
3     Mean       65          4           1 

可以使用pd.between获取所需的传感器值,然后创建多索引数据帧以改进所获取数据的显示。您将在此处找到有用的信息:如何检查熊猫中两个日期时间之间的位置日期时间和构造 3D-pandas-dataframe。你可以尝试这样的事情:

import pandas as pd
import numpy as np
import io
from statistics import mean
s_e = """Event Number    start            end
1      6/1/2020 0:00  6/1/2020 0:02
2      6/1/2020 0:05  6/1/2020 0:08"""
s_s = """   Datetime    Sensor 1     Sensor 2    Sensor 3
6/1/2020 0:00     80           4           0
6/1/2020 0:01     80           5           0
6/1/2020 0:02     69           9           1
6/1/2020 0:03     72           8           0
6/1/2020 0:04     60           9           0
6/1/2020 0:05     76           3           0
6/1/2020 0:06     62           8           1
6/1/2020 0:07     80           8           0
6/1/2020 0:08     64           7           1"""
events = pd.read_csv(io.StringIO(s_e), sep='ss+', parse_dates=[1,2], engine='python')
sensors = pd.read_csv(io.StringIO(s_s), sep='ss+', parse_dates=[0], engine='python')
#We create a dataframe with all values of ['Values','Open','Close','Min' ,'Max', 'Mean'] of each sensor
dfEveSen=pd.DataFrame()
pd.set_option('display.max_columns', None)
for sensor in sensors.columns[1:]:
#we get the sensor values between start and end of each event 
dfEveSen[sensor+'values']=[list(sensors[sensor][sensors.Datetime.between(start, end)].agg(list)) for start, end in zip(events['start'], events['end'])] 
dfEveSen['first'+sensor]=dfEveSen[sensor+'values'].apply(lambda x: x[0])
dfEveSen['last'+sensor]=dfEveSen[sensor+'values'].apply(lambda x: x[len(x)-1])
dfEveSen['min'+sensor]=dfEveSen[sensor+'values'].apply(lambda x: min(x))
dfEveSen['max'+sensor]=dfEveSen[sensor+'values'].apply(lambda x: max(x))
dfEveSen['mean'+sensor]=dfEveSen[sensor+'values'].apply(lambda x: mean(x))

#We get the data of dfEveSen to create a MultiIndex dataframe
dataa=[dfEveSen[colum] for colum in dfEveSen.columns]
dataa=np.array(dataa)
#we define the the second indexed row ['Values','Open','Close','Min' ,'Max', 'Mean']
A = np.array( ['Values','Open','Close','Min' ,'Max', 'Mean']*3)
#we define the the first indexed row: ['Sensor 1', 'Sensor 2', 'Sensor 3']
B=np.repeat(sensors.columns[1:],6)
#We create the MultiIndex dataframe called sensorevent
sensorevent = pd.DataFrame(data=dataa.T, columns=pd.MultiIndex.from_tuples(zip(B,A)))
sensorevent.index.name = 'event'
sensorevent.index +=1
print(sensorevent)
#if you want to erase the column of values try this:
#sensorevent = sensorevent.drop('Values', axis=1, level=1)
#print(sensorevent)

输出:

Sensor 1                                  Sensor 2                              Sensor 3
Values Open Close Min Max     Mean        Values Open Close Min Max Mean        Values Open Close Min Max      Mean
event
1          [80, 80, 69]   80    69  69  80  76.3333     [4, 5, 9]    4     9   4   9    6     [0, 0, 1]    0     1   0   1  0.333333
2      [76, 62, 80, 64]   76    64  62  80     70.5  [3, 8, 8, 7]    3     7   3   8  6.5  [0, 1, 0, 1]    0     1   0   1       0.5

首先,我们从事件数据帧 (df_eStartEnd创建一个IntervalIndex。使用get_indexer我们从df_e获取事件编号,并将它们作为新列分配给传感器数据帧 (df_s(。这里重要的是,get_indexer返回缺失值的-1,因此我们必须在df_e末尾为缺失事件添加相应的行,以便iloc[-1]返回此行而不是原始数据的最后一行。然后我们简单地按事件编号分组。

idx = pd.IntervalIndex.from_arrays(df_e.Start, df_e.End, 'both')
df_s.assign(event=df_e.append(pd.Series(dtype='Int64'), ignore_index=True).iloc[idx.get_indexer(df_s.Datetime), 0].values).groupby('event')[['Sensor 1', 'Sensor 2', 'Sensor 3']].agg(['first', 'last', 'min', 'max', 'mean'])

例:

import pandas as pd
import io
s_e = """Event Number    Start            End
1      6/1/2020 0:00  6/1/2020 0:02
2      6/1/2020 0:05  6/1/2020 0:08"""
s_s = """   Datetime    Sensor 1     Sensor 2    Sensor 3
6/1/2020 0:00     80           4           0
6/1/2020 0:01     80           5           0
6/1/2020 0:02     69           9           1
6/1/2020 0:03     72           8           0
6/1/2020 0:04     60           9           0
6/1/2020 0:05     76           3           0
6/1/2020 0:06     62           8           1
6/1/2020 0:07     80           8           0
6/1/2020 0:08     64           7           1"""
df_e = pd.read_csv(io.StringIO(s_e), sep='ss+', parse_dates=[1,2], engine='python')
df_s = pd.read_csv(io.StringIO(s_s), sep='ss+', parse_dates=[0], engine='python')
idx = pd.IntervalIndex.from_arrays(df_e.Start, df_e.End, 'both')
df_s.assign(event=df_e.append(pd.Series(dtype='Int64'),ignore_index=True).iloc[idx.get_indexer(df_s.Datetime),0].values).groupby('event')[['Sensor 1', 'Sensor 2', 'Sensor 3']].agg(['first', 'last', 'min', 'max', 'mean'])

结果:

Sensor 1                         Sensor 2                   Sensor 3                       
first last min max       mean    first last min max mean    first last min max      mean
event                                                                                            
1           80   69  69  80  76.333333        4    9   4   9  6.0        0    1   0   1  0.333333
2           76   64  62  80  70.500000        3    7   3   8  6.5        0    1   0   1  0.500000


此解决方案适用于大型数据集。对于 100K 行传感器数据和 5K 事件,需要 296 毫秒,而另一个pd.between答案需要 16.6 秒。

最新更新