按 pandas 中的布尔值对时间范围进行分组

zun*_*ltz 0 python pandas

我有一个带有布尔值的 pandas 时间序列:

2014-09-09 08:01:07.617    False
2014-09-09 08:01:08.617    False
2014-09-09 08:01:09.616    False
2014-09-09 08:01:10.616    False
2014-09-09 08:01:11.617     True
2014-09-09 08:01:12.616     True
2014-09-09 08:01:13.616     True
2014-09-09 08:01:14.617     True
2014-09-09 08:01:15.616     True
2014-09-09 08:01:16.616     False
2014-09-09 08:01:17.616     False
2014-09-09 08:01:18.616     False
2014-09-09 08:01:20.116     False
2014-09-09 08:01:21.116     False
Run Code Online (Sandbox Code Playgroud)

我想计算具有相同布尔值的日期范围。在上面的例子中,它将由

2014-09-09 08:01:07.617 -- 2014-09-09 08:01:10.616 False
2014-09-09 08:01:11.617 -- 2014-09-09 08:01:15.616 True
2014-09-09 08:01:16.616 -- 2014-09-09 08:01:21.116 False
Run Code Online (Sandbox Code Playgroud)

真实数据有 2e9 行。有没有办法在不迭代该系列值的情况下做到这一点?

unu*_*tbu 5

您可以使用diff/cumsum将组编号分配给布尔值。然后对组号进行分组,并使用.agg(['first', 'last'])来获取每个组中的第一个和最后一个索引:

import pandas as pd

Timestamp = pd.Timestamp
ts = pd.Series({Timestamp('2014-09-09 08:01:07.617000'): False,
                Timestamp('2014-09-09 08:01:08.617000'): False,
                Timestamp('2014-09-09 08:01:09.616000'): False,
                Timestamp('2014-09-09 08:01:10.616000'): False,
                Timestamp('2014-09-09 08:01:11.617000'): True,
                Timestamp('2014-09-09 08:01:12.616000'): True,
                Timestamp('2014-09-09 08:01:13.616000'): True,
                Timestamp('2014-09-09 08:01:14.617000'): True,
                Timestamp('2014-09-09 08:01:15.616000'): True,
                Timestamp('2014-09-09 08:01:16.616000'): False,
                Timestamp('2014-09-09 08:01:17.616000'): False,
                Timestamp('2014-09-09 08:01:18.616000'): False,
                Timestamp('2014-09-09 08:01:20.116000'): False,
                Timestamp('2014-09-09 08:01:21.116000'): False})

df = ts.reset_index()
df['groupno'] = df[0].diff().cumsum().fillna(0)

result = df.groupby(['groupno'])['index'].agg(['first', 'last'])
print(result)
Run Code Online (Sandbox Code Playgroud)

产量

                          first                    last
groupno                                                
0       2014-09-09 08:01:07.617 2014-09-09 08:01:10.616
1       2014-09-09 08:01:11.617 2014-09-09 08:01:15.616
2       2014-09-09 08:01:16.616 2014-09-09 08:01:21.116
Run Code Online (Sandbox Code Playgroud)