熊猫时间序列分裂成很多并取平均值

时间:2020-01-15 21:09:01

标签: python pandas optimization split time-series

我有以下熊猫数据框:

SEC POS DATA
1   1   4
2   1   4
3   1   5
4   1   5
5   2   2
6   3   4
7   3   2
8   4   2
9   4   2
10  1   8
11  1   6
12  2   5
13  2   5
14  2   4
15  2   6
16  3   2
17  4   1

现在,我想知道POS列每个块的DATA平均值和SEC的第一个值。 像这样:

SEC POS DATA
1   1   4.5
5   2   2
6   3   3
8   4   2
10  1   7
12  2   5
16  3   2
17  4   1

此外,我想从3个先前的DATA值中减去POS = 4的DATA值,所以POS = [1,2,3]。

获得以下内容:

SEC POS DATA
1   1   2.5
5   2   0
6   3   1
8   4   2
10  1   6
12  2   4
16  3   1
17  4   1

我想出了如何通过使用forloop将数据帧分成许多不同的数据帧来实现的方法。取平均值,然后减去其他数据帧。但是,这非常慢,所以我想知道是否有更快的方法可以帮助任何人?

谢谢!

2 个答案:

答案 0 :(得分:1)

对于您的第一个问题,我们可以使用:

14

grps = df['POS'].ne(df['POS'].shift()).cumsum()

dfg = df.groupby(grps).agg(
    POS=('POS', 'min'),
    SEC=('SEC', 'min'),
    DATA=('DATA', 'mean')
).reset_index(drop=True)

第二个问题:

   POS  SEC  DATA
0  1    1    4.5 
1  2    5    2.0 
2  3    6    3.0 
3  4    8    2.0 
4  1    10   7.0 
5  2    12   5.0 
6  3    16   2.0 
7  4    17   1.0 

grps2 = dfg['POS'].lt(dfg['POS'].shift()).cumsum()

m = (
    dfg.groupby(grps2)
       .apply(lambda x: x.loc[x['POS'].isin([1,2,3]), 'DATA'] 
              - x.loc[x['POS'].eq(4), 'DATA'].iat[0])
       .droplevel(0)
)

dfg['DATA'].update(m)

答案 1 :(得分:1)

另一种解决方案:

diff_to_previous = df.POS != df.POS.shift(1)
df = df.groupby(diff_to_previous.cumsum(), as_index=False).agg({'SEC': 'first', 'POS':'first', 'DATA':'mean'})
df['tmp'] = (df['POS'] == 4).astype(int).shift(fill_value=0).cumsum()
df['DATA'] = df.groupby('tmp')['DATA'].transform(lambda x: [*(x[x.index[:-1]] - x[x.index[-1]]), x[x.index[-1]]] )
df = df.drop(columns='tmp')

print(df)

打印:

   SEC  POS  DATA
0    1    1   2.5
1    5    2   0.0
2    6    3   1.0
3    8    4   2.0
4   10    1   6.0
5   12    2   4.0
6   16    3   1.0
7   17    4   1.0
相关问题