如果特定值后面的字符串不等于值列表,我希望删除行。具体来说,如果 'Up' or 'Left'
之后的后续行后面没有 'Right'
或 'Down'
,那么我的目标是删除这些行。
import pandas as pd
df = pd.DataFrame({
'Label' : ['A','B','A','B','B','B','A','B','B','A','A','A'],
'Item' : ['X','Left','X','Left','Down','Right','Up','Y','Right','Y','Right','Up'],
})
df1 = df[~(df['Item'].isin(['Up','Left']).shift(1)) & (df['Item'].isin(['Right','Down']))]
Label Item
0 A X
1 B Left
2 A X # Drop. Not Right/Down
3 B Left
4 B Down # Keep. Right/Down
5 B Right
6 A Up
7 B Y # Drop. Not Right/Down
8 B Right
9 A Y
10 A Right
11 A Up
预期输出:
Label Item
0 A X
1 B Left
3 B Left
4 B Down
5 B Right
6 A Up
8 B Right
9 A Y
10 A Right
11 A Up
答案 0 :(得分:4)
您的代码很好,只是缺少第二个条件中的 not
如果“Up”或“Left”之后的下一行是not,然后是 'Right' 或 'Down' 那么我的目标是删除这些行。
所以它应该是这样的:
df1 = df[~(((df['Item'].isin(['Up','Left']).shift(1)) & ~(df['Item'].isin(['Right','Down']))))]
答案 1 :(得分:2)
我修改了面具。它会立即解决您的问题 -
import pandas as pd
import numpy as np
df = pd.DataFrame({
'Label' : ['A','B','A','B','B','B','A','B','B','A','A','A'],
'Item' : ['X','Left','X','Left','Down','Right','Up','Y','Right','Y','Right','Up'],
})
mask = (~(df['Item'].isin(['Up','Left']) & (~df['Item'].shift(-1).isin(['Right','Down',np.NAN]))))
df1 = df[mask.shift(1,fill_value=True)]
print(df1)
输出 -
Label Item
0 A X
1 B Left
3 B Left
4 B Down
5 B Right
6 A Up
8 B Right
9 A Y
10 A Right
11 A Up
答案 2 :(得分:2)
首先创建一个 left up
掩码,用于确定 Left
列中 Up
和 Item
值的索引。
然后移动 left up
掩码以获得 right down
掩码,确定我们要检查的位置。
lu_mask = (df['Item'] == 'Left') | (df['Item'] == 'Up')
rd_mask = lu_mask.shift(1).fillna(False)
此外,使用 right down
掩码检查该行是 Right
还是 Down
。
index_to_drop = ((df.loc[rd_mask, 'Item'] != 'Right') & (df.loc[rd_mask, 'Item'] != 'Down')).loc[lambda s: s == True]
最后,删除该行。
df_ = df[~df.index.isin(index_to_drop.index)]
# print(df_)
Label Item
0 A X
1 B Left
3 B Left
4 B Down
5 B Right
6 A Up
8 B Right
9 A Y
10 A Right
11 A Up
答案 3 :(得分:1)
我认为这里有更简单的解决方案,如已接受的答案:
您的解决方案通过 |
按位更改 OR
并首先移动值然后比较:
df2 = df[df['Item'].isin(['Right','Down']) | ~df['Item'].shift().isin(['Up','Left'])]
print (df2)
Label Item
0 A X
1 B Left
3 B Left
4 B Down
5 B Right
6 A Up
8 B Right
9 A Y
10 A Right
11 A Up