删除值之前的所有日期

Dropping all dates before value

我有一个美国各州和日期的面板数据框。我的目标是为每个在值列中具有 0 的状态找到最新日期,然后删除直到并包括该点的所有观察值。所以作为一个 MWE:

df = pd.DataFrame({'state':['CA']*6+['MA']*6, 
               'date':list(pd.date_range('2000-1-1', freq='MS', periods=6))*2,
               'vals':[0, 2, 0, 4, 5, 6, 1, 2, 3, 4, 5, 6]}).set_index(['state', 'date'])

创建此 df:

                  vals
state date
CA    2000-01-01     0
      2000-02-01     2
      2000-03-01     0
      2000-04-01     4
      2000-05-01     5
      2000-06-01     6
MA    2000-01-01     1
      2000-02-01     2
      2000-03-01     3
      2000-04-01     4
      2000-05-01     5
      2000-06-01     6

这会找到正确的截止日期(开区间),考虑到 MA 没有零,因此没有截止日期:

cutoff_dates = df.groupby('state').apply(lambda g: g[g['vals'] == 0].index.get_level_values(1).max())

state
CA   2000-03-01
MA          NaT
dtype: datetime64[ns]

但我无法从这里开始过滤我的数据框,因此我只能观察到从 2000-4-1 开始的 CA 和从 2000-1-1 开始的 MA。我可以通过遍历 'df' 和 'cutoff_dates' 来了解这是如何完成的。 但是如何在 Pandas 和 groupby 环境中完成? 看起来应该可以,但我没有看到。

创建一个布尔掩码和一个中间组来过滤掉您的数据框:

m = df['vals'].eq(0)
g = m.cumsum()
out = df[~m & g.groupby(level=0).transform(max).eq(g)]

输出:

>>> out
                  vals
state date            
CA    2000-04-01     4
      2000-05-01     5
      2000-06-01     6
MA    2000-01-01     1
      2000-02-01     2
      2000-03-01     3
      2000-04-01     4
      2000-05-01     5
      2000-06-01     6

m&g详情:

>>> pd.concat([df, m.rename('m'), g.rename('g')], axis=1)
                  vals      m  g
state date                      
CA    2000-01-01     0   True  1
      2000-02-01     2  False  1
      2000-03-01     0   True  2
      2000-04-01     4  False  2
      2000-05-01     5  False  2
      2000-06-01     6  False  2
MA    2000-01-01     1  False  2
      2000-02-01     2  False  2
      2000-03-01     3  False  2
      2000-04-01     4  False  2
      2000-05-01     5  False  2
      2000-06-01     6  False  2