用Python求时间序列中的最大N积分

2024-04-26 12:47:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个振荡的时间序列数据,我需要找到最大的积分,也就是符号变化前的最长持续时间。为了简单起见,这里有一个例子:

In [166]: df
Out[166]: 
    c   timestamp
0   1           1
1   2           2
2   3           3
3   4           4
4   5           5
5   4           6
6   3           7
7   2           8
8   1           9
9  -1          10
10 -2          11
11 -3          12
12 -1          13
13  1          14
14  2          15
15  3          16

下面是我如何找到积分的:

import pandas as pd
import numpy as np
from itertools import tee


def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

asign = np.sign(df['c'])
signchange = ((np.roll(asign, 1) - asign) != 0).astype(int)

changes = list(signchange[signchange>0].index)
changes.insert(0, 0)
changes.append(list(df[' timestamp'].index)[-1])


integral_borders = list(pairwise(changes))


integrals = []

for (begin, end) in integral_borders:
    area = np.trapz(df['c'][begin:end])
    integrals.append((area, (begin, end)))

# this gives
# In [67]: integrals
# Out[67]: [(24.0, (0, 9)), (-6.0, (9, 13)), (1.5, (13, 15))]

我对这种方法的问题是它在计算上很昂贵。 我想改进它,这样我就不必一次读取整个数据文件。 我还认为,如果简单append,则可以有一个简单的插入排序,同时只保留一个小的N积分。你知道吗

你能指出一个方法来做这两件事吗?你知道吗


Tags: inimportdfasnpouttimestamplist
1条回答
网友
1楼 · 发布于 2024-04-26 12:47:55

你在找groupby。在熊猫中进行预处理:

df['change'] = df['c'].shift() * df['c'] < 0
df['group'] = df['change'].cumsum()

退货:

    c  timestamp change  group
0   1          1  False      0
1   2          2  False      0
2   3          3  False      0
3   4          4  False      0
4   5          5  False      0
5   4          6  False      0
6   3          7  False      0
7   2          8  False      0
8   1          9  False      0
9  -1         10   True      1
10 -2         11  False      1
11 -3         12  False      1
12 -1         13  False      1
13  1         14   True      2
14  2         15  False      2
15  3         16  False      2

然后分别对每个组应用np.trapz函数:

df.groupby('group')['c'].apply(np.trapz)

结果:

0    24.0
1    -6.0
2     4.0

编辑:为了恢复每个时段的开始和结束,可以使用firstlastgroupby方法。你知道吗

df.groupby('group')['timestamp'].first()
df.groupby('group')['timestamp'].last()

如果您想一次应用所有三个函数,可以使用agg

df.groupby('group').agg({
    'c': np.trapz,
    'timestamp': ['first', 'last']
})

相关问题 更多 >