首页 > 解决方案 > 指定值和先前值的子集 df

问题描述

我的目标是对特定值的 df 进行子集化。使用下面,这些记录在items,它们是BD。我也希望对前面的行进行子集化,BD记录在other_items( X, Y) 中。注意:我只想返回Bor之前的最后一项D。所以他们最后XY之前BD

本质上,查找包含Bor的每一行D并返回等于Xor的最后一行Y。问题是它可能事先在 1-10 行之间。

import pandas as pd

df = pd.DataFrame({   
    'Val' : [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4],             
    'ID' : ['X','Y','B','X','C','X','C','D','E','Y','Y','A','B','C','X','C','Y','D','E','A'],                 
    })

items = ['B','D']

other_items = ['X','Y']

df = df.loc[(df['ID'].isin(items)) | df['ID'].shift(-1).isin(items) & (df['ID'].isin(other_items))]

预期输出:

    Val ID
1     1  Y
2     1  B
5     2  X
7     2  D
10    3  Y
12    3  B
16    4  Y
17    4  D

标签: pythonpandas

解决方案


首先通过对两个列表求和仅过滤行,然后按上一个和下一个值过滤:

items = ['B','D']
other_items = ['X','Y']

df = df[df['ID'].isin(other_items + items)]

m1 = df['ID'].isin(other_items) & df['ID'].shift(-1).isin(items)
m2 = df['ID'].isin(items) & df['ID'].shift().isin(other_items)

如果需要按组处理:

m1 = df['ID'].isin(other_items) & df.groupby('Val')['ID'].shift(-1).isin(items)
m2 = df['ID'].isin(items) & df.groupby('Val')['ID'].shift().isin(other_items)

最后一个过滤器:

df = df[m1 | m2]
print (df)
    Val ID
1     1  Y
2     1  B
5     2  X
7     2  D
10    3  Y
12    3  B
16    4  Y
17    4  D

推荐阅读