满足条件后按组获取上一行的值

时间:2020-05-25 19:32:38

标签: python pandas group-by

我有以下问题。这是我的数据框:

district    curfew_name        active   value    date
  A            np.nan            0       10       1
  A             B1               1       20       4
  A             B1               1       21       6
  C             D1               1       14       8      
  C             D1               1       16       11
  C             D2               1       14       13
  E             F1               0       30       10
  E             F1               1       14       12

因此,每行是一个日期(每行之间2-3天),其中district可能已启用宵禁。因此,我想知道对于每个宵禁,该宵禁第一次激活前的日期该区域的value列的值是多少。因此,在这种情况下,宵禁B1在日期4被激活,因此我检查了该区域的前一个value,它是10。对于宵禁D1,我没有知道那个地区以前的value是什么,所以我会得到一个nan。对于D2,先前的值是D1的最后一个值:16。最后,对于F1,我们看到它是事先宣布的,因此在激活之前,得到0。无论如何,该值为30。因此,我的最终Series如下所示:

curfew_name    previous_value
    B1              10
    D1             np.nan
    D2              16
    F1              30

因此,我可以像这样获得每个宵禁的初次出现:

df[df.active.eq(1)].reset_index().groupby('curfew_name').first()['index']

然后我只是尝试减去一个,然后提取这些索引:

idx = df[df.active.eq(1)].reset_index().groupby('curfew_name').first()['index'] - 1

但是对于D1这样的情况,这会给我一个21,这是另一个地区的值。你会怎么做?我已经尝试过groupby('district')shift()eq()的一些组合,但是我仍然没有以有效的方式使它组合。

谢谢!

编辑:我现在的方法是获取先前的索引,然后检查与该索引关联的行是否与原始索引位于同一区域,并在满足该条件时过滤它们,但是我很确定我可以做得更好。

2 个答案:

答案 0 :(得分:0)

IIUC:

(df.assign(previous_value=df.groupby('district').value.shift())  # usual groupby.shift
   .drop_duplicates(['district','curfew_name'])                  # drop all duplicates
  [['curfew_name','previous_value']]                             # select the columns of interest
   .dropna(subset=['curfew_name'])                               # ignore curfew with nan values
)

输出:

  curfew_name  previous_value
1          B1            10.0
3          D1             NaN
5          D2            16.0
7          F1            30.0

答案 1 :(得分:0)

从@Quang Hoang的回答中得到启发,我的最初方法是设法做到这一点:

df['previous_value'] = df.groupby('district').value.shift()
idx = df[df.active.eq(1)].reset_index().groupby('curfew_name').first()['index']
previous_values = df[df.index.isin(idx )].set_index('curfew_name').previous_value
相关问题