我有一个主数据框,其中包含批号和日期时间范围,这些批次的发生方式如下:
BatchNo StartTime Event A Event B
BATCH23797 2013-09-06 02:22:00 0 0
BATCH23798 2013-09-06 06:06:00 0 0
BATCH23799 2013-09-06 14:33:00 0 0
BATCH23800 2013-09-06 18:12:00 0 0
BATCH23801 2013-09-06 21:38:00 0 0
然后我对我感兴趣的事件有另外一个时间戳。我有多个这些时间戳的数据格式不同但是一天结束时我会得到一个与事件对应的dateTimes列表。我使用df.index来获取下面的时间戳列表:
DateTime Event A Flag
2013-09-06 03:20:18 1
2013-09-06 12:09:50 1
2013-09-06 13:19:45 1
2013-09-06 19:09:35 1
我想要做的是从这个事件时间列表中。填充顶部数据框,以便计算该日期范围内发生的事件数量。每个批次的时间长度不同,我也需要考虑到这一点。所以最后顶部的数据框将如下所示:
BatchNo StartTime Event A Event B
BATCH23797 2013-09-06 02:22:00 1 0
BATCH23798 2013-09-06 06:06:00 2 0
BATCH23799 2013-09-06 14:33:00 0 0
BATCH23800 2013-09-06 18:12:00 1 0
BATCH23801 2013-09-06 21:38:00 0 0
对于批次,批次的完成时间是下一批次的开始时间(因此始终有批次)。
非常感谢任何帮助。
Caz没有回答我自己的问题,但这是我提出的:
在花了好几个小时试图自己这样做之后,我设法在提出问题后自己回答。
我是这样做的。对于我所做的任何改进,我们将不胜感激。
我使用下一批的开始时间创建了另一个名为Endtime的列,然后切断了
的最后一个值df["EndTime"] = df["StartTime"].shift(-1)
df = df[:-1]
然后我使用这个函数来查找时间戳在开始和结束之间的位置,然后执行1 * bool来添加事件。我使用events.index作为事件列表,它运行良好。
def collateEvents(masterdf, eventList, columnName):
# For each event
for i in range(len(eventList)):
#Get a dataframe which says where this event is true
eventSeries = (df["StartTime"] < eventList[i]) & (df["EndTime"] > eventList[i])
#Add one onto the columnName if the event is true
masterdf[columnName] = masterdf[columnName] + (1 * eventSeries)
return masterdf
答案 0 :(得分:0)
我们可以假设批处理表中的StartTime
已排序吗?如果是这样的话,我想你可以做到如下,如果没有,那么,先把它排序。这是一个想法,两个表是这样的:
## batch table ##
BatchNo StartTime
0 BATCH23797 2013-09-06 02:22:00
1 BATCH23798 2013-09-06 06:06:00
2 BATCH23799 2013-09-06 14:33:00
3 BATCH23800 2013-09-06 18:12:00
4 BATCH23801 2013-09-06 21:38:00
## event table ##
DateTime Event A Flag Event B Flag
0 2013-09-06 03:20:18 1 1
1 2013-09-06 12:09:50 1 0
2 2013-09-06 13:19:45 1 0
3 2013-09-06 19:09:35 1 1
我调用了第一个batch
表和第二个event
,我还为Event B flag
添加了一些非零值以进行演示。第一件事是对event.DateTime
上的每个batch.StartTime
执行二进制搜索,以找出事件发生的批处理作业。 (从技术上讲,你可以在这里做二分搜索,但没关系。)
使用bisect
模块很容易。我们首先需要在batch
表中找到相应的表索引,然后找到批号:
import bisect
# a helper function to perform binary search
hit_idx = lambda x: bisect.bisect_left( batch.StartTime, x ) - 1
idx = event.DateTime.map( hit_idx )
event[ 'BatchNo' ] = map( batch.BatchNo.get, idx )
这将是输出:
DateTime Event A Flag Event B Flag BatchNo
0 2013-09-06 03:20:18 1 1 BATCH23797
1 2013-09-06 12:09:50 1 0 BATCH23798
2 2013-09-06 13:19:45 1 0 BATCH23798
3 2013-09-06 19:09:35 1 1 BATCH23800
现在,您只需按BatchNo
分组并添加事件:
pv = event.groupby( 'BatchNo' )['Event A Flag', 'Event B Flag'].aggregate( sum )
输出:
Event A Flag Event B Flag
BatchNo
BATCH23797 1 1
BATCH23798 2 0
BATCH23800 1 1
现在,如果你想现在批处理BATCH23798
期间发生了每种类型的事件数量
你只需在数据透视表中查找:
pv.ix[ 'BATCH23798' ]
输出:
Event A Flag 2
Event B Flag 0
为了让生活更轻松,我们可以重新索引数据透视表:
pv.reindex( batch.BatchNo ).fillna( 0 )
输出:
Event A Flag Event B Flag
BatchNo
BATCH23797 1 1
BATCH23798 2 0
BATCH23799 0 0
BATCH23800 1 1
BATCH23801 0 0