Если хотите удалить последнюю in
только для групп, инвертируйте маску цепи с Series.duplicated
на ~
с не равным in
с Series.ne
:
df = df[~df['id'].duplicated() | df['product'].ne('in')]
print (df)
id product date
0 220 in 2014-09-01
1 220 out 2014-09-03
3 826 in 2014-11-11
4 826 out 2014-12-09
5 826 out 2014-05-19
6 901 in 2014-09-01
7 901 out 2014-10-05
8 901 out 2014-11-01
РЕДАКТИРОВАТЬ:
Если хотите, чтобы все возможные пары in-out
для групп использовали это решение , только необходимые сопоставления не числовые значения in-out
с числовыми с dict
,потому что rolling
не работает со строками:
#more general solution
print (df)
id product date
0 220 out 2014-09-03
1 220 out 2014-09-03
2 220 in 2014-09-01
3 220 out 2014-09-03
4 220 in 2014-10-16
5 826 in 2014-11-11
6 826 in 2014-11-11
7 826 out 2014-12-09
8 826 out 2014-05-19
9 901 in 2014-09-01
10 901 out 2014-10-05
11 901 in 2014-09-01
12 901 out 2014-11-01
pat = np.asarray(['in','out'])
N = len(pat)
d = {'in':0, 'out':1}
ma = (df['product'].map(d)
.groupby(df['id'])
.rolling(window=N , min_periods=N)
.apply(lambda x: (x==list(d.values())).all(), raw=False)
.mask(lambda x: x == 0)
.bfill(limit=N-1)
.fillna(0)
.astype(bool)
.reset_index(level=0, drop=True)
)
df = df[ma]
print (df)
id product date
2 220 in 2014-09-01
3 220 out 2014-09-03
6 826 in 2014-11-11
7 826 out 2014-12-09
9 901 in 2014-09-01
10 901 out 2014-10-05
11 901 in 2014-09-01
12 901 out 2014-11-01