Select某列某值的前一行

Select the previous row of a certain value in a column

我的清单数据包含列:sale_datesaleIDregionproduct。每个 region 中的每个 product 都可以在 region 中多次出售,但每次都有唯一的 saleID.

现在,我有一个 saleID 的列表,我需要 select saleID 所在的行。此外,我需要在该区域中找到该产品的最后一个 saleID(和整行)。换句话说,我需要先按 regionproduct 分组,然后在列表中找到 saleID 并在分组的行中找到这个 saleID 的前一行

df
sale_date     saleID       region     product     
2017-05-01    A12           Asia       car1
2018-03-05    B21           Asia       car1
2018-04-01    C23           Asia       car1
2018-09-06    C21           Canada     car2
2019-01-01    E11           Canada     car2
2019-03-02    E23           USA        car3
2019-01-02    G41           USA        car3
2015-02-02    H11           Mexico     car4
2015-02-03    I14           Mexico     car4

预期输出

saleID_list = [B21, E11, I14]
sale_date     saleID       region     product     
2017-05-01    A12           Asia       car1
2018-03-05    B21           Asia       car1
2018-09-06    C21           Canada     car2
2019-01-01    E11           Canada     car2
2015-02-02    H11           Mexico     car4
2015-02-03    I14           Mexico     car4

我知道我们可以 select 使用

列出 saleID 的行
df.loc[df['saleID'].isin(saleID_list)]

但是我能找到groupby数据的前一行吗?我试图写一些类似使用 shift 的东西,但是 AttributeError: 'DataFrameGroupBy' object has no attribute 'loc'

df.groupby(['region', 'product']).loc[df['saleID'].isin(saleID_list)].shift(1)

DataFrameGroupBy.shift for helper Series and test it in Series.isin 与原始掩码一起用于测试列 saleID| 链接用于按位 OR:

saleID_list = ["B21", "E11", "I14"]

s = df.groupby(['region', 'product'])['saleID'].shift(-1)

df = df[df['saleID'].isin(saleID_list) | s.isin(saleID_list)]
print (df)
    sale_date saleID  region product
0  2017-05-01    A12    Asia    car1
1  2018-03-05    B21    Asia    car1
3  2018-09-06    C21  Canada    car2
4  2019-01-01    E11  Canada    car2
7  2015-02-02    H11  Mexico    car4
8  2015-02-03    I14  Mexico    car4