python - 根据值删除pandas groupby中的项目
问题描述
我有一个这样的数据框:
ID A B C
"Z" "apple" 1 5
"Z" "pear" 3 1
"C" "apple" 1 8
"E" "strawberry" 2 5
"E" "pear" 5 1
"D" "apple" 1 5
"D" "pear" 3 1
"D" "melon" 1 5
对于具有相同id的那些,我想按如下方式过滤行:如果一个ID下有两条记录,其中一条是“apple”,我想删除包含“apple”的行。如果我有两个以上的记录,其中一个是“apple”,并且如果我有多个该 ID 的记录并且没有一个是“apple”,我想删除属于该 ID 的所有记录。所以df应该是这样的:
ID A B C
"Z" "pear" 3 1
"C" "apple" 1 8
我猜测起点应该是按 ID 分组的,但我不知道如何编写一个函数来完成其余的工作。
解决方案
按位boolean indexing
与链式掩码一起使用:|
OR
#filter apples
m0 = df['A'].eq('apple')
#get counts per groups
s = df.groupby('ID')['ID'].transform('size')
#check if at least one apple per group
m2 = m0.groupby(df['ID']).transform('any')
#chain mask with length 2, at least one apple and all not apples OR
#length 1 with apples
df = df[(s.eq(2) & ~m0 & m2) | (s.eq(1) & m0)]
print (df)
ID A B C
1 Z pear 3 1
2 C apple 1 8
详情:
with pd.option_context('expand_frame_repr', False):
print (df.assign(m = m0,
s = s,
m2 = m2,
s2 = s.eq(2),
invm0 = ~m0,
first = (s.eq(2) & ~m0 & m2),
s1 = s.eq(1),
second = (s.eq(1) & m0),
both =(s.eq(2) & ~m0 & m2) | (s.eq(1) & m0)
))
ID A B C m s m2 s2 invm0 first s1 second both
0 Z apple 1 5 True 2 True True False False False False False
1 Z pear 3 1 False 2 True True True True False False True
2 C apple 1 8 True 1 True False False False True True True
3 E strawberry 2 5 False 2 False True True False False False False
4 E pear 5 1 False 2 False True True False False False False
5 D apple 1 5 True 3 True False False False False False False
6 D pear 3 1 False 3 True False True False False False False
7 D melon 1 5 False 3 True False True False False False False
推荐阅读
- reactjs - 如何使用“严格”模式在 React 中调试控制台警告?
- tensorflow - 在 tensorflow 2.1.0 中使用什么代替 tf.contrib.layers.embed_sequence
- azure - Azure Log Analytics 和 App Insights 是否能够适应 Azure 区域内的数据中心故障
- ruby - 可以在 rspec 中使用花括号来阻止它吗?
- r - 如何使用 Tidymodels 获得 PCA 累积比例?
- java - 为什么运算符不给出不同的结果而是使用 = 给出正确的答案
- algorithm - 以下算法近似于什么?(假设 m>1,ε>0)
- angular - 如何在有限的资源和旧计算机上运行 Angular 构建
- ios - Objective-C 块:不兼容的块指针类型
- c# - 正则表达式匹配文件路径有或没有空格