Python 从其他数据帧创建新的pandas timeseries数据帧
如何从一个现有df创建新的pandas timeseries数据帧 假设事件A开始于11/28 11:35,结束于11/29 19:53,这是计数1。同样,事件A第二个实例开始于11月28日11:37,结束于11月29日19:53-计数另一个1。所以我把A的值增加到2。(抱歉,数据输入错误地为11/28,而不是11/29) Source df提供事件的开始和结束时间。同一事件可以同时发生多次。 新df应具有给定分钟内事件累积计数的时间序列,范围从最小值(开始时间)到最大值(结束时间) 资料来源:Python 从其他数据帧创建新的pandas timeseries数据帧,python,pandas,time-series,Python,Pandas,Time Series,如何从一个现有df创建新的pandas timeseries数据帧 假设事件A开始于11/28 11:35,结束于11/29 19:53,这是计数1。同样,事件A第二个实例开始于11月28日11:37,结束于11月29日19:53-计数另一个1。所以我把A的值增加到2。(抱歉,数据输入错误地为11/28,而不是11/29) Source df提供事件的开始和结束时间。同一事件可以同时发生多次。 新df应具有给定分钟内事件累积计数的时间序列,范围从最小值(开始时间)到最大值(结束时间) 资料来源:
开始时间|结束时间|事件
2014年11月28日11:35 | 2014年11月29日19:53 | A
2014年11月28日11:36 | 2014年11月28日11:37 | B
2014年11月28日11:32 | 2014年11月28日19:53 | C
2014年11月28日11:37 | 2014年11月28日19:53 | A
......
新Df:
TimeStamp | A | B | C
11/28/2014 11:35 | 1 | 0 | 1
11/28/2014 11:36 | 1 | 1 | 1
11/28/2014 11:37 | 2 | 1 | 1
.....
11/29/2014 19:53 | 2 | 0 | 1
这有点棘手,因为您希望结束时间算作“打开”状态,但我认为类似的方法应该可以工作(警告:我花了零时间考虑奇怪的边缘情况,所以买家要小心):
产生
>>> df_out
Signal
Event A B C
Time
11/28/2014 11:32 0 0 1
11/28/2014 11:35 1 0 1
11/28/2014 11:36 1 1 1
11/28/2014 11:37 2 1 1
11/28/2014 19:53 2 0 1
11/29/2014 19:53 1 0 0
基本思想是添加一个有符号的“信号”列,并使用该列跟踪更改:
>>> df
Event Time Signal
0 A 11/28/2014 11:35 1
1 B 11/28/2014 11:36 1
2 C 11/28/2014 11:32 1
3 A 11/28/2014 11:37 1
4 A 11/29/2014 19:53 -1
5 B 11/28/2014 11:37 -1
6 C 11/28/2014 19:53 -1
7 A 11/28/2014 19:53 -1
>>> pivoted
Signal
Event A B C
Time
11/28/2014 11:32 0 0 1
11/28/2014 11:35 1 0 0
11/28/2014 11:36 0 1 0
11/28/2014 11:37 1 -1 0
11/28/2014 19:53 -1 0 -1
11/29/2014 19:53 -1 0 0
然后我们可以将其旋转以获得状态更改:
>>> df
Event Time Signal
0 A 11/28/2014 11:35 1
1 B 11/28/2014 11:36 1
2 C 11/28/2014 11:32 1
3 A 11/28/2014 11:37 1
4 A 11/29/2014 19:53 -1
5 B 11/28/2014 11:37 -1
6 C 11/28/2014 19:53 -1
7 A 11/28/2014 19:53 -1
>>> pivoted
Signal
Event A B C
Time
11/28/2014 11:32 0 0 1
11/28/2014 11:35 1 0 0
11/28/2014 11:36 0 1 0
11/28/2014 11:37 1 -1 0
11/28/2014 19:53 -1 0 -1
11/29/2014 19:53 -1 0 0
并累积以获得状态:
>>> pivoted.cumsum()
Signal
Event A B C
Time
11/28/2014 11:32 0 0 1
11/28/2014 11:35 1 0 1
11/28/2014 11:36 1 1 1
11/28/2014 11:37 2 0 1
11/28/2014 19:53 1 0 0
11/29/2014 19:53 0 0 0
这几乎是我们想要的,但您希望包括结束时间,因此我们可以通过取消关闭来延迟效果:
>>> pivoted.cumsum() + (pivoted == -1)
Signal
Event A B C
Time
11/28/2014 11:32 0 0 1
11/28/2014 11:35 1 0 1
11/28/2014 11:36 1 1 1
11/28/2014 11:37 2 1 1
11/28/2014 19:53 2 0 1
11/29/2014 19:53 1 0 0
这里有一个与@DSM稍有不同的方法。我将
start
和end
列堆叠在一起,然后在length
上使用groupby
和aggregate
函数进行过滤。然后,为了获得所需的外观输出,Ipivot
table
start = [35, 36, 37, 36, 35]
end = [56, 56, 56, 58, 58]
events = ['A', 'B', 'C', 'A', 'A']
df = pd.DataFrame( {'start': start, 'end': end, 'events': events})
# stack the 'start' and 'end' columns here
new_df = pd.DataFrame({ 'times': df['start'].append(df['end']), 'events': df['events'].append(df['events']) })
new_df = new_df.groupby(['times', 'events']).agg(len)
# massage the data frame to conform to desired output
new_df = new_df.reset_index().pivot('times', 'events').fillna(0)
连接的数据帧如下所示:
events times
0 A 35
1 B 36
2 C 37
3 A 36
4 A 35
0 A 56
1 B 56
2 C 56
3 A 58
4 A 58
groupby
分组后的数据帧:
times events
35 A 2
36 A 1
B 1
37 C 1
56 A 1
B 1
C 1
58 A 2
最后是枢轴后的数据帧:
events A B C
times
35 2 0 0
36 1 1 0
37 0 0 1
56 1 1 1
58 2 0 0
我认为@DSM的解决方案在计算时间方面比我的更有效,因为
append
方法成本相当高,因为它需要在每次调用时构造一个全新的对象。不过,我没有对这两种方法进行计时,所以我不确定。您是否需要在特定时间分钟内开始或结束的事件的累计计数?是的。假设事件A开始于11/28 11:35,结束于11/29 19:53,这是计数1。同样,事件A第二个实例开始于11月28日11:37,结束于11月29日19:53-计数另一个1。所以我把A的值增加到2。(抱歉,数据输入错误地为11/28,而不是11/29)