我的目标是根据特定值对 df 进行子集化。使用下面的方法,这些记录在items
中,分别是B
和D
。我还希望对 B
之前的行进行子集化和D
记录在 other_items
( X
, Y
)。注意:我只想返回 B
之前的最后一项或D
。所以它们持续X
, Y
之前B
, D
.
本质上,找到包含 B
的每一行或D
并返回等于 X
的最后一行或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
最佳答案
首先按两个列表的总和仅过滤行,然后按上一个和下一个值过滤:
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
关于python - 指定值和先前值的子集 df,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65389344/