如何按组筛选cum_sum小于组内最大值80%的Pandas DataFrame子集?
按组筛选cum_sum小于组内最大值80%记录的解决方法
咱们先聊聊你之前代码里的问题哈:你写的grouped.filter(lambda x: x[x.cum_sum] <= x[x.cum_sum.max()])有几个小误区:
- 访问DataFrame的列得用
x['cum_sum'],x[x.cum_sum]会把cum_sum的数值当成列名来索引,这肯定不对 - 需求是小于组内最大值的80%,你没乘以0.8,反而和最大值本身比了,不符合要求
x[x.cum_sum.max()]也是错误的写法,获取组内最大值应该用x['cum_sum'].max()
下面给你两种简单可行的正确写法,都能实现你的需求:
方法一:用transform广播组内阈值,直接筛选
这种方法会给每条记录匹配它所在组的最大值80%,然后直接做条件过滤,逻辑很直观:
import pandas as pd # 你的原始数据 d = {'group': ['a', 'b', 'c', 'b', 'b', 'c', 'a', 'b', 'a'], 'cum_sum': [1, 4, 3, 9, 15, 6, 3, 17, 4]} df = pd.DataFrame(data=d) # 计算每个group的cum_sum最大值的80%,并把这个值对应到组内每一行 group_max_80 = df.groupby('group')['cum_sum'].transform(lambda x: x.max() * 0.8) # 筛选出cum_sum小于该阈值的记录 result = df[df['cum_sum'] < group_max_80] print(result)
运行结果:
group cum_sum 0 a 1 1 b 4 2 c 3 3 b 9 5 c 6 6 a 3
(解释下:比如group a的最大值是4,80%是3.2,所以a组里只有1、3符合小于3.2的要求;group b最大值17,80%是13.6,所以4、9符合,15和17都超过了;group c最大值6,80%是4.8,只有3符合)
方法二:用groupby.filter直接过滤行
如果你想用filter方法,只要修正lambda里的逻辑就行——lambda接收每个分组的DataFrame,返回该分组中符合条件的行的布尔序列:
result = df.groupby('group').filter(lambda x: x['cum_sum'] < x['cum_sum'].max() * 0.8)
这个写法和方法一的结果完全一致,适合喜欢用groupby链式操作的场景。
内容的提问来源于stack exchange,提问作者milka1117
相关产品推荐
相关产品推荐

