Python 尝试使用Pandas操作传感器时间数据
我想看看是否有一种方法可以使用熊猫来进行以下计算: 我有一个表,表中有事件编号,后跟它们各自的开始和结束日期时间Python 尝试使用Pandas操作传感器时间数据,python,pandas,Python,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
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
是否有一种方法可以运行原始表并根据开始和结束时间戳裁剪此表
我试图让最后一张表看起来像是包含
- 打开
- 接近
- 闵
- 马克斯
- 卑鄙
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
首先,我们在事件数据帧(df_e
)中创建一个fromStart
和End
。我们使用从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='\s\s+', parse_dates=[1,2], engine='python')
df_s = pd.read_csv(io.StringIO(s_s), sep='\s\s+', 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秒。您可以使用来获取所需的传感器值,然后创建一个用于改进所获得数据的显示。您将在此处找到有用的信息:和。您可以尝试以下方法:
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='\s\s+', parse_dates=[1,2], engine='python')
sensors = pd.read_csv(io.StringIO(s_s), sep='\s\s+', 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
你能提供一个理想最终结果的简单例子吗?所以我们可以想象它应该是什么样子。我把它作为问题的一个编辑添加了进去。谢谢。你知道为什么从Spyder或Jupyter笔记本执行时,以及从cmd执行时,会抛出
ValueError:no results
,它会工作吗?@MrNobody33:no。在Spyder(python 3.8.2,pandas 1.0.4)中运行该示例时,我没有发现任何错误。如果你对答案投了反对票,也许你可以解释一下为什么这个答案没有用?