繁体   English   中英

删除组中的行,直到最后一行满足某些条件

[英]Remove rows in a group by until the last row meets some condition

我有以下 df

  id  type 

0 1    A   
1 1    B
2 1    A
3 2    A
4 2    B
5 3    A
6 3    B
7 3    A
8 3    B
9 3    A
10 3   A

我们可以假设此数据已经排序。 我需要做的是,对于每个 id,我需要在以下条件下删除行

  1. 每个 id 的第一个条目是类型A
  2. 每个 id 的最后一个条目是类型B
  3. 最后一个条目的B是最后一个出现的(数据已经排序)

我已经完成了 1. 具有以下内容:

df = df.groupby('id').filter(lambda x: x['Type'].iloc[0] != 'A')

如果他们的第一个类型不是A ,它会完全删除 ids

但是,对于 2. 和 3.,如果最后一个类型不是B ,我不想删除 id ,相反我只想删除中间的所有内容

结果 df:

 id  type 

0 1    A   
1 1    B
3 2    A
4 2    B
5 3    A
8 3    B

示例代码:

d = {'id': {0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 3, 6: 3, 7: 3, 8: 3, 9: 3, 10: 3},
 'type': {0: 'A',
  1: 'B',
  2: 'A',
  3: 'A',
  4: 'B',
  5: 'A',
  6: 'B',
  7: 'A',
  8: 'B',
  9: 'A',
  10: 'A'}}

df = pd.DataFrame.from_dict(d)

看来您可以根据type使用具有不同规则的drop_duplicates

out = pd.concat([df.query("type=='A'").drop_duplicates(subset=['id','type'], keep='first'), 
                 df.query("type=='B'").drop_duplicates(subset=['id','type'], keep='last')]).sort_index()

Output:

   id type
0   1    A
1   1    B
3   2    B
4   2    A
5   3    A
8   3    B

您可以简单地使用掩码来分割 DataFrame:

m1 = df['type'].eq('B')
# first non-duplicate
m2 = ~df.duplicated(keep='first')
# last non-duplicate
m3 = ~df.duplicated(keep='last')

df[(m1&m2).shift(-1)|(m1&m3)]

# (m1&m2).shift(-1) -> value before the first B (i.e an A)
# (m1&m3)           -> last B

output:

   id type
0   1    A
1   1    B
3   2    A
4   2    B
5   3    A
8   3    B

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM