如何移除Pandas DataFrame中含全值为0子组的name分组
移除存在全0子组的Name分组
原始数据构造
import pandas as pd d = {"name": ['peter', 'peter', 'peter', 'peter', 'peter', 'peter', 'david', 'david', 'david', 'david', 'david', 'david'], "class": ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'C', 'A', 'B', 'C'], "value": [2, 0, 3, 5, 0, 0, 4, 7, 0, 9, 1, 0]} df = pd.DataFrame(data=d)
需求说明
按name和class分组后,只要某个name对应的分组里,存在至少一个class子组的value全部为0,就把这个name的所有行都删掉。比如示例里david的class C子组所有value都是0,所以要移除david的所有行,只保留peter的记录。
实现代码
# 找出所有需要移除的name:存在全0class子组的name bad_names = df.groupby(['name', 'class'])['value'].apply(lambda x: (x == 0).all()).groupby('name').any() bad_names = bad_names[bad_names].index # 过滤掉这些name的所有行 result = df[~df['name'].isin(bad_names)] print(result)
代码说明
- 先按
name+class分组,用(x == 0).all()判断每个子组的value是不是全为0,得到每个子组的布尔结果 - 再按
name聚合,用any()判断该name下是否存在至少一个全0的子组,得到每个name的布尔标记 - 提取出标记为
True的name(也就是要移除的名单) - 最后用
isin和取反操作,过滤掉这些name的所有行,得到最终结果
最终输出
name class value 0 peter A 2 1 peter B 0 2 peter A 3 3 peter B 5 4 peter A 0 5 peter B 0
内容的提问来源于stack exchange,提问作者sampeterson
相关产品推荐
相关产品推荐

