我需要在情况发生前60分钟(例如在“信号” == 1列中的数字之前60秒)切片熊猫时间序列。
现在,我在整个数据帧上使用.tail(60)直到所需的索引,但这效率非常低
def create_sequences(signal, label, data):
"""Function to return seqs of 60 secs prior to condition"""
sequences = []
for i in signal:
sequence = data.loc[:i].tail(60)
if len(sequence) == 60:
sequences.append((np.array(sequence.drop('Signal',
axis=1)).transpose(), label))
return sequences
# To generate some data for reproduction
periods = 7 * 24 * 60
tidx = pd.date_range('2019-09-01', periods=periods, freq='T')
ts = pd.DataFrame(data=data, index=tidx)
ts['Signal'] = ts[0].apply(lambda x: 1 if x > 0 else 0)
ones = ts[ts.Signal == 1].index.values
x = create_sequences(ones, 1, ts)
答案 0 :(得分:1)
我已经稍微修改了数据生成脚本,
periods = 7 * 24 * 60
tidx = pandas.date_range('2019-09-01', periods=periods, freq='T')
ts = pandas.DataFrame(index=tidx)
ts['Signal'] = 0
在第1000行(超过10080行)中引入了“ 1”,
ts['Signal'].iloc[1000] = 1
首先只需快速检查一下时间戳索引是否已排序
In[1]: ts.index.is_monotonic_increasing
Out[1]: True
导入tqdm
以衡量效果
from tqdm import tqdm
两个选项,因为时间序列的分辨率为1分钟,所以这里的结果将是相同的,但是您可以根据期望的结果使用一个或另一个。
1。如果要使生成的切片像滑动窗口一样重叠,则可以使用.iterrows()
D = pandas.Timedelta('00:00:60')
sequences = []
for timestamp, row in tqdm(ts.iterrows()):
if ts.loc[timestamp:timestamp + D, 'Signal'].sum() > 0:
break
sequences.append(ts.loc[timestamp:timestamp + D])
2。如果您希望得到的切片是连续的且不重叠,
D = pandas.Timedelta('00:00:60')
sequences = []
nmax = numpy.trunc((ts.index.max() - ts.index.min()) / D)
for n in range(0, int(nmax)):
if ts.loc[ts.index.min() + (n * D):ts.index.min() + (1 + n) * D, 'Signal'].sum() > 0:
break
sequences.append(ts.loc[ts.index.min() + (n * D):ts.index.min() + (1 + n) * D])
两次执行均低于一秒,但是如果您寻求更快的性能,则可以检查.itertuples()
(参考https://medium.com/@formigone/stop-using-df-iterrows-2fbc2931b60e)
答案 1 :(得分:0)
这是有效的,但是对于大型数据集来说有点慢
sequences = []
for timestamp, row in ts.iterrows():
data = ts.loc[timestamp:timestamp + pd.Timedelta(seconds=60),:]
label = ts.Signal.loc[timestamp + pd.Timedelta(seconds=60)]
sequences.append((ts.drop('Signal', axis=1).values, label))