gpt4 book ai didi

python - 在 numpy (pandas) 中合并时间上彼此接近的事件

转载 作者:太空宇宙 更新时间:2023-11-04 05:24:56 24 4
gpt4 key购买 nike

我想简化开始和停止时间的列表。当一个停止和另一个开始之间的时间时,我想合并(行)。以下是我的数据的简化以及我希望作为输出的内容:

import numpy as np
import pandas as pd
start_time = [ 1, 7, 20, 22, 27, 35]
stop_time = [ 5, 9, 22, 26, 30, 40]
events = pd.DataFrame({'start_time': start_time, 'stop_time': stop_time})
allowable_gap = 2.0

desired_start_time = [ 1, 20, 35]
desired_stop_time = [ 9, 30, 40]
desired_events = pd.DataFrame({'start_time':desired_start_time, 'stop_time':desired_stop_time})

我没有要求必须使用 Pandas。但是,我至少需要使用 numpy。事件个数在1e6的数量级。

感谢任何实现或指导。我知道我的部分问题是我没有“理解”Pandas。

我的用法可能与解决方案无关。作为背景,我正在收集大量事件,然后使用 matplotlib.pyplot 绘制它们。由于输出很复杂,我发现最好的格式是 .svg。 IE 通常可以很好地渲染,但需要很长时间才能完成,我希望减少它必须绘制的线条数。我很想以更好的方式查看时间序列,但这超出了这个问题的范围。

最佳答案

更有效的方法:

In [106]: (events.groupby((events.start_time - events.stop_time.shift() > allowable_gap).cumsum())
.....: .agg({'start_time':'min', 'stop_time':'max'})[['start_time','stop_time']])
Out[106]:
start_time stop_time
0 1 9
1 20 30
2 35 40

针对 60K 行 DF 的计时:

In [129]: events = pd.concat([events] * 10**4, ignore_index=True)

In [130]: events.shape
Out[130]: (60000, 2)

In [131]: %paste
def f():
desired_start_time = []
desired_stop_time = []

start = None
end = None
for index, row in events.iterrows():
if start == None and end == None:
start = row['start_time']
end = row['stop_time']
else:
if end + allowable_gap >= row['start_time']:
end = row['stop_time']
else:
desired_start_time.append(start)
desired_stop_time.append(end)
start = row['start_time']
end = row['stop_time']
desired_start_time.append(start)
desired_stop_time.append(end)
## -- End pasted text --

In [132]: %timeit f()
1 loop, best of 3: 16.1 s per loop

In [133]: %%timeit
.....: (events.groupby((events.start_time - events.stop_time.shift() > allowable_gap).cumsum())
.....: .agg({'start_time':'min', 'stop_time':'max'})[['start_time','stop_time']])
.....:
100 loops, best of 3: 16.9 ms per loop

结论:“循环”解决方案大约是。慢 1000 倍

6M 行 DF 的另一个时序:

In [153]: events = pd.concat([events] * 10**6, ignore_index=True)

In [154]: events.shape
Out[154]: (6000000, 2)

In [155]: %%timeit
.....: (events.groupby((events.start_time - events.stop_time.shift() > allowable_gap).cumsum())
.....: .agg({'start_time':'min', 'stop_time':'max'})[['start_time','stop_time']])
.....:
1 loop, best of 3: 1.49 s per loop

给定和期望的 DF:

In [98]: events
Out[98]:
start_time stop_time
0 1 5
1 7 9
2 20 22
3 22 26
4 27 30
5 35 40

In [99]: desired_events
Out[99]:
start_time stop_time
0 1 9
1 20 30
2 35 40

解释:

In [107]: events.start_time - events.stop_time.shift()
Out[107]:
0 NaN
1 2.0
2 11.0
3 0.0
4 1.0
5 5.0
dtype: float64

In [108]: (events.start_time - events.stop_time.shift() > allowable_gap)
Out[108]:
0 False
1 False
2 True
3 False
4 False
5 True
dtype: bool

In [109]: (events.start_time - events.stop_time.shift() > allowable_gap).cumsum()
Out[109]:
0 0
1 0
2 1
3 1
4 1
5 2
dtype: int32

关于python - 在 numpy (pandas) 中合并时间上彼此接近的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39152864/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com