【问题标题】:Get previous row value by group after condition is met满足条件后按组获取上一行值
【发布时间】:2020-05-25 19:32:38
【问题描述】:

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

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() 的一些组合,但我仍然没有以一种有效的方式做到这一点。

谢谢!

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

【问题讨论】:

    标签: python pandas group-by


    【解决方案1】:

    从@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
    

    【讨论】:

      【解决方案2】:

      你可以试试这个:

      (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
      

      【讨论】:

      • 感谢@Quang Hoang!我的例子似乎没有完全涵盖可能的情况,所以我会相应地更新。其要点是有时会提前宣布宵禁,因此curfew_name 可能在激活之前将active 设为零
      • 我设法做到了,从您的回答中获得灵感!我会发布我所做的,但我不确定为什么你的选择不起作用
      猜你喜欢
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      • 2018-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-13
      • 2020-11-04
      相关资源
      最近更新 更多