首页 > 解决方案 > Datetime .shift(-1) 的行之间的更改未返回正确的行

问题描述

我有以下数据框,索引为 datetime64[ns]。

                           Side
CollectionTimestamp (CST)      
2020-01-06 08:35:00        High
2020-01-06 09:25:00         Low *******
2020-01-06 09:30:00         Low
2020-01-06 09:35:00         Low
2020-01-06 09:40:00         Low
2020-01-06 09:45:00         Low
2020-01-06 09:50:00         Low
2020-01-06 09:55:00         Low
2020-01-06 10:00:00         Low
2020-01-06 10:05:00         Low
2020-01-06 10:10:00         Low
2020-01-06 10:15:00         Low
2020-01-06 10:20:00         Low
2020-01-06 10:25:00         Low
2020-01-06 10:30:00         Low
2020-01-06 10:35:00         Low
2020-01-06 10:40:00         Low
2020-01-06 10:45:00         Low
2020-01-06 10:50:00         Low
2020-01-06 10:55:00         Low
2020-01-06 11:00:00         Low
2020-01-08 08:35:00        High
2020-01-08 10:15:00         Low *******
2020-01-08 10:20:00         Low
2020-01-08 10:30:00         Low
2020-01-08 10:35:00         Low
2020-01-08 10:40:00         Low
2020-01-08 10:45:00         Low
2020-01-08 10:50:00         Low
2020-01-08 10:55:00         Low
2020-01-08 11:00:00         Low

我想要一个新的数据框,其中 df['Side'] 不等于上一行(我已经放置了****,将在新的数据框中)但是 groupby 日期,因为数据框将有几天不是变化。

df.dtypes()
Side    object

我试过这段代码:

df = df.loc[(df['Side'] != df['Side'].shift(-1))]

它返回以下内容:

                           Side
CollectionTimestamp (CST)      
2020-01-06 08:35:00        High
2020-01-06 11:00:00         Low
2020-01-08 08:35:00        High
2020-01-08 11:00:00         Low

第一次更改的行不正确,它似乎抓住了最后一次更改?

为什么不能不返回:

                           Side
CollectionTimestamp (CST)     
2020-01-06 09:25:00         Low
2020-01-08 10:15:00         Low

.shift(-1) 不正确吗?

我试图做一个 df.groupby(df.index.date),但这也没有用,所以我想我在这里遗漏了一些东西。

我试过这个,但它也不正确:

df['C'] = df['Side'].shift(-1)
df = df.loc[(df['Side'] != df['C'])

标签: pythonpandasdataframedatetimetime-series

解决方案


因为您想在一天之内执行此操作,并且可能有几天没有差异,您可以使用 groupby andapply` 您的子集逻辑。这不是cythonized,因此对于较大的DataFrame,它往往会变慢。有一些技巧可以让您利用 cython 中实现的 groupby 操作,但它确实混淆了逻辑。

res = (df.groupby(df.index.date, group_keys=False)
         .apply(lambda gp: gp[gp['Side'].ne(gp['Side'].shift().fillna(gp['Side']))]))

res
                          Side
CollectionTimestamp (CST)     
2020-01-06 09:25:00        Low
2020-01-08 10:15:00        Low

推荐阅读